Map對象
Map對象是一種有對應 鍵/值 對的對象, JS的Object也是 鍵/值 對的對象 ;
ES6中Map相對於Object對象有幾個區別:
1:Object對象有原型, 也就是說他有默認的key值在對象上面, 除非我們使用Object.create(null)創建一個沒有原型的對象;
2:在Object對象中, 只能把String和Symbol作為key值, 但是在Map中,key值可以是任何基本類型(String, Number, Boolean, undefined, NaN....),或者對象(Map, Set, Object, Function , Symbol , null....);
3:通過Map中的size屬性, 可以很方便地獲取到Map長度, 要獲取Object的長度, 你只能用別的方法了;
Map實例對象的key值可以為一個數組或者一個對象,或者一個函數,比較隨意 ,而且Map對象實例中數據的排序是根據用戶push的順序進行排序的, 而Object實例中key,value的順序就是有些規律了, (他們會先排數字開頭的key值,然后才是字符串開頭的key值);
Map實例的屬性
map.size這個屬性和數組的length是一個意思,表示當前實例的長度;
Map實例的方法
clear()方法, 刪除所有的鍵/值對;
delete(key), 刪除指定的鍵/值對;
entries()返回一個迭代器, 迭代器按照對象的插入順序返回[key, value];
forEach(callback , context) 循環執行函數並把鍵/值對作為參數; context為執行函數的上下文this;
get(key) 返回Map對象key相對應的value值;
has(key) 返回布爾值, 其實就是返回Map對象是否有指定的key;
keys() 返回一個迭代器,迭代器按照插入的順序返回每一個key元素;
set(key, value) 給Map對象設置key/value 鍵/值對, 返回這個Map對象(相對於Javascript的Set,Set對象添加元素的方法叫做add,而Map對象添加元素的方法為set;
[@@iterator] 和entrieds()方法一樣, 返回一個迭代器, 迭代器按照對象的插入順序返回[key, value];
自己模擬一個Map構造器:
既然知道了Map對象的方法和屬性, 我們也可以自己模擬一個Map構造器, 需要生成器的支持, 所以要在ES5中使用還需要生成器的補丁(模擬Set構造器) :
<html>
<head>
<meta charMap="utf-8">
</head>
<body>
<script>
"use strict";
class Map {
/**
* @param [[key, value], [k, val]];
* @return void;
*/
static refresh (arg) {
for(let [key,value] of arg) {
//判斷是否重復了;
let index = Map.has.call(this, key);
if(index===false) {
this._keys.push(key);
this._values.push(value);
}else{
//如果有重復的值,那么我們執行覆蓋;
this._keys[index] = key;
this._values[index] = value;
}
};
this.size = this._keys.length;
}
/**
* @desc return false || Number;
* */
static has (key) {
var index = this._keys.indexOf(key);
if(index === -1) {
return false;
}else{
return index;
};
}
constructor(arg) {
this._keys = [];
this._values = [];
Map.refresh.call(this, arg);
}
set (key, value) {
Map.refresh.call(this, [[key,value]]);
return this;
}
clear () {
this._keys = [];
this._values = [];
return this;
}
delete (key) {
var index = Map.has.call(this, key);
if(index!==false) {
this._keys.splice(index,1);
this._values.splice(index,1);
};
return this;
}
entries () {
return this[Symbol.iterator]();
}
has (key) {
return Map.has.call(this, key) === false ? false : true;
}
*keys() {
for(let k of this._keys) {
yield k;
}
}
*values () {
for(let v of this._values) {
yield v;
}
}
//直接使用數組的forEach方便啊;
forEach (fn, context) {
return this;
}
//必須支持生成器的寫法;
*[Symbol.iterator] (){
for(var i=0; i<this._keys.length; i++) {
yield [this._keys[i], this._values[i]];
}
}
};
var map = new Map([["key","value"]]);
map.set("heeh","dada");
console.log(map.has("key")); //輸出:true;
map.delete("key");
console.log(map.has("key")); //輸出:false;
map.set("key","value");
var keys = map.keys();
var values = map.values();
console.log(keys.next());
console.log(keys.next());
console.log(values.next());
console.log(values.next());
var entries = map.entries();
console.log(entries);
</script>
</body>
</html>
Map的使用Demo:
var myMap = new Map(); var keyString = "a string", keyObj = {}, keyFunc = function () {}; // 我們給myMap設置值 myMap.set(keyString, "字符串'"); myMap.set(keyObj, "對象"); myMap.set(keyFunc, "函數"); myMap.size; // 輸出長度: 3 // 獲取值 console.log(myMap.get(keyString)); // 輸出:字符串 console.log(myMap.get(keyObj)); // 輸出:對象 console.log(myMap.get(keyFunc)); // 輸出:函數 console.log(myMap.get("a string")); // 輸出:字符串 console.log(myMap.get({})); // 輸出:undefined console.log(myMap.get(function() {})) // 輸出:undefined
我們也可以把NaN,undefined, 對象,數組,函數等這些作為一個Map對象的key值 :
"use strict"; let map = new Map(); map.set(undefined, "0"); map.set(NaN, {}); console.log(map); //輸出:Map { undefined => '0', NaN => {} }
循環Map的方法
使用Map實例的forEach方法;
"use strict"; let map = new Map(); map.set(undefined, "0"); map.set(NaN, {}); map.forEach(function(value ,key ,map) { console.log(key,value, map); });
使用for...of循環:
"use strict"; let map = new Map(); map.set(undefined, "0"); map.set(NaN, {}); for(let [key, value] of map) { console.log(key, value); } for(let arr of map) { console.log(arr); }
WeakMap
WeakMap是弱引用的Map對象, 如果對象在js執行環境中不存在引用的話,相對應的WeakMap對象內的該對象也會被js執行環境回收;
WeakMap對象的屬性:無
WeakMap對象的方法:
delete(key) : 刪除指定的鍵/值對;
get(key) :返回Map對象key相對應的value值;
has(key) :返回布爾值, 其實就是返回Map對象是否有指定的key;
set(key):給Map對象設置key/value 鍵/值對, 返回這個Map對象;
WeakMap相對於Map少了很多的方法, 我們也可以自己再來實現這些方法,比如我們再實現一個Map實例的clear方法:
class ClearableWeakMap { constructor(init) { this._wm = new WeakMap(init) } clear() { this._wm = new WeakMap() } delete(k) { return this._wm.delete(k) } get(k) { return this._wm.get(k) } has(k) { return this._wm.has(k) } set(k, v) { this._wm.set(k, v) return this } }
參考:
MDN:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map;
ruanyifeng:http://es6.ruanyifeng.com/#docs/set-map
作者: NONO
出處:http://www.cnblogs.com/diligenceday/
QQ:287101329
微信:18101055830
