晴明的博客园 GitHub      CodePen      CodeWars     

[ES6] Set、Map

 #

Map
new Map([iterable])     

返回一个新的Map对象。

如果参数iterable是一个数组或者其他可迭代的对象--它的元素是键值对,
这样这些的每一个键值对都可以添加到新的Map里面去

Map对象就是简单的键/值映射.其中键和值可以是任意值(原始值或对象值).

在判断两个值是否为同一个键的时候,使用的并不是===运算符,而是使用了一种称之为"same-value"的内部算法,
该算法很特殊, 对于Map对象来说, +0 (按照以往的经验与 -0 是严格相等的)和-0 是两个不同的键.
而NaN在作为Map对象的键时和另外一个NaN是一个相同的键(尽管NaN !== NaN).

Object和Map的比较

Object和Map类似的一点是,它们都允许你按键存取一个值,都可以删除键,还可以检测一个键是否绑定了值.

因此,一直以来,我们都把对象当成Map来使用,不过,现在有了Map,下面的区别解释了为什么使用Map更好点:
    一个对象通常都有自己的原型,所以一个对象总有一个"prototype"键.不过,现在可以使用map = Object.create(null)来创建一个没有原型的对象.
    一个对象的键只能是字符串,但一个Map的键可以是任意值.
    可以很容易的得到一个Map的键值对个数,而只能跟踪一个对象的键值对个数

 

Map.prototype.size
Map.prototype.clear()
Map.prototype.delete(key)
Map.prototype.entries()
Map.prototype.forEach(callbackFn[, thisArg])
Map.prototype.get(key)
Map.prototype.has(key)
Map.prototype.keys()
Map.prototype.set(key, value)
Map.prototype.values()
Map.prototype[@@iterator]()

 

#Using the Map object

            var myMap = new Map();
            var keyObj = {},
                keyFunc = function() {},
                keyString = "a string";
            // 添加键
            myMap.set(keyString, "和键'a string'关联的值");
            myMap.set(keyObj, "和键keyObj关联的值");
            myMap.set(keyFunc, "和键keyFunc关联的值");
            console.log(myMap.size); // 3
            // 读取值
            console.log(myMap.get(keyString));  // "和键'a string'关联的值"
            console.log(myMap.get(keyObj));  // "和键keyObj关联的值"
            console.log(myMap.get(keyFunc));  // "和键keyFunc关联的值"
            console.log(myMap.get("a string"));  // "和键'a string'关联的值"
            // 因为keyString === 'a string'
            
            console.log(myMap.get({})); // undefined, 因为keyObj !== {}
            console.log(myMap.get(function() {})); // undefined, 因为keyFunc !== function () {}

 

NaN 也可以作为Map对象的键. 虽然 NaN 和任何值甚至和自己都不相等(NaN !== NaN 返回true),
#两个NaN作为Map的键来说是没有区别的

            var myMap = new Map();
            myMap.set(NaN, "not a number");
            console.log(myMap.get(NaN)); // "not a number"
            var otherNaN = Number("foo");
            console.log(myMap.get(otherNaN)); // "not a number"

#Iterating Maps with for..of

Maps can be iterated using a for..of loop:

            var myMap = new Map();
            myMap.set(0, "zero");
            myMap.set(1, "one");
            for (var [key, value] of myMap) {
                console.log(key + " = " + value);
            }
            //0 = zero
            //1 = one
            // Will show 2 logs; first with "0 = zero" and second with "1 = one"
            for (var key of myMap.keys()) {
                console.log(key);
            }
            // Will show 2 logs; first with "0" and second with "1"
            for (var value of myMap.values()) {
                console.log(value);
            }
            // Will show 2 logs; first with "zero" and second with "one"
            for (var [key, value] of myMap.entries()) {
                console.log(key + " = " + value);
            }
            // Will show 2 logs; first with "0 = zero" and second with "1 = one"

 #Iterating Maps with forEach()

Maps can be iterated using the forEach() method

            var myMap = new Map();
            myMap.set(0, "zero");
            myMap.set(1, "one");
            myMap.forEach(function(value, key) {
                    console.log(key + " = " + value);
                }, myMap)
                // Will show 2 logs; first with "0 = zero" and second with "1 = one"

 

 

Map.prototype.size

size 可访问属性返回 Map 对象的元素数量.

size 属性的值是一个整数,表示 Map 对象有多少个键值对。
size 是只读属性,它对应的 set 方法是 undefined,即不能改变它的值。
#

        var myMap = new Map();
            myMap.set("a", "alpha");
            myMap.set("b", "beta");
            myMap.set("g", "gamma");
            console.log(myMap.size); // 3

 

Map.prototype[@@toStringTag]

Map[Symbol.toStringTag]

The Map[@@toStringTag] property has an initial value of "Map".

#

Object.prototype.toString.call(new Map()) // "[object Map]"

 

 

Map.prototype.set()

myMap.set(key, value);

The set() method adds a new element with a specified key and value to a Map object.

#

    var myMap = new Map();
            // Add new elements to the map
            myMap.set("bar", "foo");
            console.log(myMap.get("bar")); //  "foo"
            myMap.set(1, "foobar");
            // Update an element in the map
            myMap.set("bar", "baz");
            
            console.log(myMap.get("bar")); // "baz"
            console.log(myMap.get(1)); // "foobar"

 

 

Map.prototype.get()

myMap.get(key);

get() 方法用来获取一个 Map对象中指定的元素。

#

        var myMap = new Map();
            myMap.set("bar", "foo");
            console.log(myMap.get("bar")); // "foo"
            console.log(myMap.get("baz")); // undefined

 

Map.prototype.values()

myMap.values()

The values() method returns a new Iterator object that contains the values for each element in the Map object in insertion order.
#

            var myMap = new Map();
            myMap.set("0", "foo");
            myMap.set(1, "bar");
            myMap.set({}, "baz");
            var mapIter = myMap.values();
            console.log(mapIter.next().value); // "foo"
            console.log(mapIter.next().value); // "bar"
            console.log(mapIter.next().value); // "baz"

 

Map.prototype.keys()

myMap.keys()

The keys() method returns a new Iterator object that contains the keys for each element in the Map object in insertion order.

#

        var myMap = new Map();
            myMap.set("0", "foo");
            myMap.set(1, "bar");
            myMap.set({}, "baz");
            var mapIter = myMap.keys();
            console.log(mapIter.next().value); // "0"
            console.log(mapIter.next().value); // 1
            console.log(mapIter.next().value); // Object {}

 

Map.prototype.entries()

myMap.entries()

The entries() method returns a new Iterator object that contains the [key, value] pairs for each element in the Map object in insertion order.

#

            var myMap = new Map();
            myMap.set("0", "foo");
            myMap.set(1, "bar");
            myMap.set({}, "baz");
            var mapIter = myMap.entries();
            console.log(mapIter.next().value); // ["0", "foo"]
            console.log(mapIter.next().value); // [1, "bar"]
            console.log(mapIter.next().value); // [Object, "baz"]

 

Map.prototype[@@iterator]()

myMap[Symbol.iterator]

The initial value of the @@iterator property is the same function object as the initial value of the entries property.

#[Symbol.iterator]

            var myMap = new Map();
            myMap.set("0", "foo");
            myMap.set(1, "bar");
            myMap.set({}, "baz");
            var mapIter = myMap[Symbol.iterator]();
            console.log(mapIter.next().value); // ["0", "foo"]
            console.log(mapIter.next().value); // [1, "bar"]
            console.log(mapIter.next().value); // [Object, "baz"]

#Using [@@iterator]() with for..of

    var myMap = new Map();
            myMap.set("0", "foo");
            myMap.set(1, "bar");
            myMap.set({}, "baz");
            for (var v of myMap) {
                console.log(v);
            }
            // ["0", "foo"]
            // [1, "bar"]
            // [Object, "baz"]

 

Map.prototype.has()

myMap.has(key);

方法has() 返回一个bool值,用来表明map 中是否存在指定元素.

#

        var myMap = new Map();
            myMap.set("bar", "foo");
            console.log(myMap.has("bar")); // returns true
            console.log(myMap.has("baz")); // returns false

 


Map.prototype.delete()
 
delete()删除Map实例key指定的值。

#

    var myMap = new Map();
            myMap.set("bar", "foo");
            console.log(myMap.get("bar"));//"foo"
            
            console.log(myMap.delete("bar")); // Returns true. Successfully removed.
            console.log(myMap.has("bar")); // Returns false. The "bar" element is no longer present.

 

Map.prototype.clear()

myMap.clear();

clear()方法会移除Map对象中的所有元素。

#

            var myMap = new Map();
            myMap.set("bar", "baz");
            console.log(myMap.set(1, "foo"));//Map {"bar" => "baz", 1 => "foo"}
            console.log(myMap);//Map {"bar" => "baz", 1 => "foo"}
            console.log(myMap.size); // 2
            console.log(myMap.has("bar")); // true
            myMap.clear();
            console.log(myMap.size); // 0
            console.log(myMap.has("bar")); // false

 

Map.prototype.forEach()

myMap.forEach(callback[, thisArg])

将会以插入顺序对 Map 对象中的每一个键值对执行一次参数中提供的回调函数。

#

        function logMapElements(value, key, map) {
                console.log("m[" + key + "] = " + value);
            }
            new Map([
                ["foo", 3],
                ["bar", {}],
                ["baz", undefined]
            ]).forEach(logMapElements);
            // logs:
            // "m[foo] = 3"
            // "m[bar] = [object Object]"
            // "m[baz] = undefined"

 

 

WeakMap

WeakMap.prototype.delete(key)
WeakMap.prototype.get(key)
WeakMap.prototype.has(key)
WeakMap.prototype.set(key, value)

 

WeakMap对象就是简单的键/值映射.但键只能是对象值,不可以是原始值.

弱引用, WeakMap 的keys无法遍历

 

#

    var wm1 = new WeakMap(),
        wm2 = new WeakMap(),
        wm3 = new WeakMap();
    var o1 = {},
        o2 = function(){},
        o3 = window;

    console.log(wm1.set(o1, 37));
    console.log(wm1.set(o2, "azerty"));
    console.log(wm2.set(o1, o2)); // value可以是任意值,包括一个对象
    console.log(wm2.set(o3, undefined));
    console.log(wm2.set(wm1, wm2)); // 键和值可以是任意对象,甚至另外一个WeakMap对象

    console.log(wm1.get(o2)); // "azerty"
    console.log(wm2.get(o2)); // undefined,wm2中没有o2这个键
    console.log(wm2.get(o3)); // undefined,值就是undefined

    console.log(wm1.has(o2)); // true
    console.log(wm2.has(o2)); // false
    console.log(wm2.has(o3)); // true (即使值是undefined)

    console.log(wm3.set(o1, 37));
    console.log(wm3.get(o1)); // 37
    
    console.log(wm1.has(o1));   // true
    console.log(wm1.delete(o1));
    console.log(wm1.has(o1));   // false

 


 

Set
new Set([iterable]);

集合(Set)对象允许你存储任意类型的唯一值(不能重复),无论是primitive values还是对象引用。

Set对象是值的集合,你可以按照插入的顺序迭代它的元素。
Set中的元素只会出现一次,即 Set 中的元素是唯一的。
因为Set中的值总是唯一的,所以需要判断两个值是否相等。

Set.prototype.size
Set.prototype.add(value)
Set.prototype.clear()
Set.prototype.delete(value)
Set.prototype.entries()
Set.prototype.forEach(callbackFn[, thisArg])
Set.prototype.has(value)
Set.prototype.keys()
Set.prototype.values()
Set.prototype[@@iterator]()

 

#

            var mySet = new Set();
            mySet.add(1);
            mySet.add(5);
            mySet.add("some text");
            console.log(mySet);//Set {1, 5, "some text"}
            console.log(mySet.has(1)); // true
            console.log(mySet.has(3)); // false, 3没有被添加到set中
            console.log(mySet.has(5)); // true
            console.log(mySet.has(Math.sqrt(25))); // true
            console.log(mySet.has("Some Text".toLowerCase())); // true
            console.log(mySet.size); // 3
            mySet.delete(5); // 从set中移除5
            console.log(mySet.has(5)); // false, 5已经被移除
            console.log(mySet.size); // 2, 我们刚刚移除了一个值

#迭代Set

            var mySet = new Set();
            mySet.add(1);
            mySet.add("some text");
        
            // 迭代整个set
            
            // 按顺序输出:1, "some text" 
            for (let item of mySet) console.log(item);
            
            // 按顺序输出:1, "some text" 
            for (let item of mySet.keys()) console.log(item);
            
            // 按顺序输出:1, "some text" 
            for (let item of mySet.values()) console.log(item);
            
            // 按顺序输出:1, "some text" 
            //(键与值相等)
            for (let [key, value] of mySet.entries()) console.log(key);
            
            // 转换Set为Array (with Array comprehensions)
            //var myArr = [v for (v of mySet) ]; // false  [1, "some text"] 
            
            // 替代方案(with Array.from)
            var myArr = Array.from(mySet); // false  [1, "some text"]
            console.log(myArr);// [1, "some text"]
            
            // 如果在HTML文档中工作,也可以:
            mySet.add(document.body);
            mySet.has(document.querySelector("body")); // true
            
            // Set和Array互换
            mySet2 = new Set([1, 2, 3, 4]);
            console.log(mySet2.size); // 4
            [...mySet2]; // [1,2,3,4]
            
            // 截取  
            //var intersection = new Set([x for (x of set1) if (set2.has(x)) ]);
            // 用forEach迭代
            mySet2.forEach(function(value) {
                console.log(value);
            });
            // 1
            // 2
            // 3
            // 4

#和Array对象的关系

            var myArray = ["value1", "value2", "value3"];
            // 用Set构造器将Set转换为Array
            var mySet = new Set(myArray);
            console.log(mySet.has("value1")); // true

 

Set.prototype.add()

mySet.add(value);

add() 方法用来给一个 Set 对象添加元素。

#

            var mySet = new Set();
            mySet.add(1);
            mySet.add(5).add("some text"); // 可以链式调用
            console.log(mySet);
            // Set [1, 5, "some text"]

 

 

WeakSet

 new WeakSet([iterable]);
 
一个 WeakSet 对象是一个无序的集合, 可以用它来存储任意的对象值,
并且对这些对象值保持弱引用.

它和 Set 对象的区别有两点:
1.WeakSet 对象中只能存放对象值, 不能存放原始值, 而 Set 对象都可以.
2.WeakSet 对象中存储的对象值都是被弱引用的, 如果没有其他的变量或属性引用这个对象值,
则这个对象值会被当成垃圾回收掉. 正因为这样, WeakSet 对象是无法被枚举的, 没有办法拿到它包含的所有元素.

WeakSet.prototype.add(value)
WeakSet.prototype.delete(value)
WeakSet.prototype.has(value)

 

#

    var ws = new WeakSet();
    var obj = {};
    var foo = {};

    ws.add(window);
    ws.add(obj);

    console.log(ws.has(window)); // true
    console.log(ws.has(foo));    // false    foo has not been added to the set

    ws.delete(window); // removes window from the set
    console.log(ws.has(window));    // false     window has been removed

 

posted @ 2016-05-23 16:51  晴明桑  阅读(168)  评论(0编辑  收藏  举报