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);
}
weakmapweakmap是弱引用的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
  }
}
以上就是详细介绍es6新特性 -javascript中的map和weakmap对象的代码实例的内容。
   
 
   