ES6 Set和Map对象

目录

Set

Map

1. Set

(1)什么是Set对象?

Set对象一些元素的集合。可以在其中添加及移除元素。它类似于数组,但又有着很大区别。

语法:

new Set([iterable]);

其中:

  • 参数:iterable

    如果传递一个可迭代对象,它的所有元素将不重复地被添加到新的 Set中。如果不指定此参数或其值为null,则新的 Set为空。

  • 返回值:一个新的Set对象。

(2)Set 中的特殊值

Set 对象存储的值总是唯一的,所以需要判断两个值是否恒等。有几个特殊值需要特殊对待:

  • +0-0在存储判断唯一性的时候是恒等的,所以不重复;

  • undefinedundefined 是恒等的,所以不重复;

  • NaNNaN是不恒等的,但是在 Set 中只能存一个,不重复。

  • {}被认为是不同的

    扫描二维码关注公众号,回复: 10557854 查看本文章
var set = new Set([{},{}])
set  //{{},{}}
set.size  // 2

var set = new Set([NaN,NaN])
set  //{NaN}
set.size  // 1

(3)Set对象的属性方法

  • size:

    该属性值为Set对象中保存的元素的数量。

    let mySet1 = new Set([1,2,3,4]);
    mySet1.size; // 4
    [...mySet1]; // [1,2,3,4]
    
    let mySet2 = new Set("一二三四");
    console.log(mySet2.size); //4
    mySet2.add("四");
    console.log(mySet2.size); //4
    
  • add()

    方法用来向一个 Set 对象的末尾添加一个指定的值。返回该对象。注意:不能添加重复的值。

    var mySet = new Set();
     
    mySet.add(1);
    mySet.add(5).add("some text"); // 可以链式调用
     
    console.log(mySet);
    // Set [1, 5, "some text"]
     
    mySet.add(5).add(1); // 重复的值不会被添加进去
    console.log(mySet); // {1, 5, "some text"}
    
  • clear():

    方法用来清空一个 Set 对象中的所有元素。返回值:undefined

    mySet.clear();
    
  • delete()

    方法可以从一个 Set 对象中删除指定的元素。成功删除返回 true,否则返回 false。

    var mySet = new Set();
    mySet.add("foo");
     
    mySet.delete("bar"); // 返回 false,不包含 "bar" 这个元素
    mySet.delete("foo"); // 返回 true,删除成功
     
    mySet.has("foo");    // 返回 false,"foo" 已经成功删除
    
  • has()

    方法返回一个布尔值来指示对应的值value是否存在Set对象中。

    var mySet = new Set();
    mySet.add('foo');
     
    mySet.has('foo');  // 返回 true
    mySet.has('bar');  // 返回 false
     
    var set1 = new Set();
    var obj1 = {'key1': 1};
    set1.add(obj1);
     
    set1.has(obj1);        // 返回 true
    set1.has({'key1': 1}); // 会返回 false,因为其是另一个对象的引用
    set1.add({'key1': 1}); // 现在 set1 中有2条(不同引用的)对象了
    
  • entries()

    该方法返回一个新的迭代器对象 ,这个对象的元素是类似 [value, value] 形式的数组,value 是集合对象中的每个元素,迭代器对象元素的顺序即集合对象中元素插入的顺序。由于集合对象不像 Map 对象那样拥有 key,然而,为了与 Map 对象的 API 形式保持一致,故使得每一个 entry 的 key 和 value 都拥有相同的值,因而最终返回一个 [value, value] 形式的数组。
    返回值:一个新的包含 [value, value] 形式的数组迭代器对象,value 是给定集合中的每个元素,迭代器 对象元素的顺序即集合对象中元素插入的顺序。

    var mySet = new Set();
    mySet.add("foobar");
    mySet.add(1);
    mySet.add("baz");
     
    var setIter = mySet.entries(); // SetIterator {"foobar" => "foobar", 1 => 1, "baz" => "baz"}
     
    console.log(setIter.next().value); // ["foobar", "foobar"]
    console.log(setIter.next().value); // [1, 1]
    console.log(setIter.next().value); // ["baz", "baz"]
    
  • values():

    该方法返回一个新的迭代器对象,该迭代器对象按照原Set 对象元素的插入顺序返回其所有元素。

  • keys() :
    返回值:将返回一个新生成的可迭代对象,以插入 Set 对象的顺序返回其包含的每个元素的值。

  • forEach(callback, thisArg) 方法会根据集合中元素的插入顺序,依次执行提供的回调函数。
    callback:回调函数有三个参数:

    • 元素的值
    • 元素的索引
    • 正在遍历的集合对象

    thisArg:回调函数执行过程中的 this 值。可选。

    function logSetElements(value1, value2, set) {
        console.log("s[" + value1 + "] = " + value2, set);
    }
     
    new Set(["foo", "bar", undefined]).forEach(logSetElements);
     
    // logs:
    // "s[foo] = foo" Set(3) {"foo", "bar", undefined}
    // "s[bar] = bar" Set(3) {"foo", "bar", undefined}
    // "s[undefined] = undefined" Set(3) {"foo", "bar", undefined}
    

(4)Set应用实例

  • 数组去重

    [...new Set([1, 3, 3, 34, 555, 2, 2])] // [1, 3, 34, 555, 2]
    
    function dedupe(array) {
      return Array.from(new Set(array));
    }
    
    dedupe([1, 1, 2, 3]) // [1, 2, 3]
    arrRemove([1, 3, 3, 34, 555, 2, 2]) // [1, 3, 34, 555, 2]
    function arrRemove (arr) {
        let tempArr = arr
        arr = []
        let set = new Set(tempArr)
        for (let i of set) {
            arr.push(i)
        }
        return arr
    }
    
  • 去除字符串里面的重复字符

    [...new Set('ababbc')].join('')
    // "abc"
    
  • set对象与数组之间的转换

    var arr = [1,2,3,4,4];
    var set = new Set(arr) //数组转换set对象
    set //{1,2,3,4}
    //方法一
    Array.from(set) //[1,2,3,4]
    //方法二
    [...set] //[1,2,3,4]
    
  • 数组去重 & 并集

    let arr1 = [1,2,3,4,5];
    let arr2 = [4,5,6,7,8];
    let a = new Set(arr1);
    let b= new Set(arr2)
    
    new Set([...arr1,...arr2]) //{1,2,3,4,5,6,7,8}
    let arr3 = [...new Set([...arr1,...arr2])] //[1,2,3,4,5,6,7,8]
    
  • 交集

    let arr3 = new Set(arr1.filter(x=>b.has(x))) //{4,5}
    
  • 差集

    let arr3 = new Set(arr1.filter(x=>!b.has(x))) //{1,2,3}
    let arr4 = new Set(arr2.filter(x=>!a.has(x))) //{6,7,8}
    [...arr3,...arr4] //[1,2,3,6,7,8]
    

参考学习于:

《HTML 5 与 CSS3权威指南》

ES6之Set对象详解

2. Map

(1)什么是Map对象?

JavaScript 的对象(Object),本质上是键值对的集合(Hash 结构),但是传统上只能用字符串当作键,这给它的使用带来了很大的限制。

为了解决这个问题,ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。

语法

new Map([iterable])

其中:

  • 参数:iterable

    Iterable 可以是一个数组或者其他 iterable 对象,其元素为键值对(两个元素的数组,例如: [[ 1, ‘one’ ],[ 2, ‘two’ ]])。 每个键值对都会添加到新的 Map。null 会被当做 undefined。

Map的key

//key 是字符串
var myMap = new Map();
var keyString = "a string"; 
 
myMap.set(keyString, "和键'a string'关联的值");
 
myMap.get(keyString);    // "和键'a string'关联的值"
myMap.get("a string");   // "和键'a string'关联的值"
                         // 因为 keyString === 'a string'
//key 是对象
var myMap = new Map();
var keyObj = {}, 
 
myMap.set(keyObj, "和键 keyObj 关联的值");

myMap.get(keyObj); // "和键 keyObj 关联的值"
myMap.get({}); // undefined, 因为 keyObj !== {}

//key 是函数
var myMap = new Map();
var keyFunc = function () {}, // 函数
 
myMap.set(keyFunc, "和键 keyFunc 关联的值");
 
myMap.get(keyFunc); // "和键 keyFunc 关联的值"
myMap.get(function() {}) // undefined, 因为 keyFunc !== function () {}

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

(2)Map 和 Objects 的区别

  • 一个 Object 的键只能是字符串或者 Symbols,但一个 Map 的键可以是任意值。
  • Map 中的键值是有序的(FIFO 原则),而添加到对象中的键则不是。
  • Map 的键值对个数可以从 size 属性获取,而 Object 的键值对个数只能手动计算。
  • Map 可直接进行迭代,而 Object 的迭代需要先获取它的键数组,然后再进行迭代。
  • Object 都有自己的原型,原型链上的键名有可能和你自己在对象上的设置的键名产生冲突。
  • Map 在涉及频繁增删键值对的场景下会有些性能优势。

(3)Map对象的属性方法

  • size

    该属性返回 Map 对象中保存的键名/键值的数量。

    const map = new Map();
    map.set('foo', true);
    map.set('bar', false);
    map.size // 2
    
  • set(key, value)

    set方法设置键名key对应的键值为value,然后返回整个 Map 结构。如果key已经有值,则键值会被更新为value,否则就新生成该键。

    set方法返回的是当前的Map对象,因此可以采用链式写法。

    const m = new Map();
     
    m.set('edition', 6)        // 键是字符串
    m.set(262, 'standard')     // 键是数值
    m.set(undefined, 'nah')    // 键是 undefined
    
    
    let map = new Map()
      .set(1, 'a')
      .set(2, 'b')
      .set(3, 'c');
    
  • get(key)

    get方法读取key对应的键值,如果找不到key,返回undefined

    const m = new Map();
     
    const hello = function() {console.log('hello');};
    m.set(hello, 'Hello ES6!') // 键是函数
     
    m.get(hello)  // Hello ES6!
    
  • has(key)

    has方法返回一个布尔值,表示某个键是否在当前 Map 对象之中。

    const m = new Map();
     
    m.set('edition', 6);
    m.set(262, 'standard');
    m.set(undefined, 'nah');
     
    m.has('edition')     // true
    m.has('years')       // false
    m.has(262)           // true
    m.has(undefined)     // true
    
  • delete(key)

    delete方法删除某个键,返回true。如果删除失败,返回false

    const m = new Map();
    m.set(undefined, 'nah');
    m.has(undefined)     // true
     
    m.delete(undefined)
    m.has(undefined)       // false
    
  • clear()

    移除Map对象中保存的所有键名/键值对,方法没有返回值

    let map = new Map();
    map.set('foo', true);
    map.set('bar', false);
     
    map.size // 2
    map.clear()
    map.size // 0
    
  • keys()

    返回一个新的 Iterator 对象。它包含按照顺序插入 Map 对象中每个元素的key值。

  • values()

    该方法返回一个新的Iterator对象。它包含按顺序插入Map对象中每个元素的value值。

  • entires():

    该方法返回一个新的Iterator对象。它包含按顺序插入Map对象中每个。

    var myMap = new Map();
    myMap.set(0, "零");
    myMap.set(1, "一");
    for (let key of myMap.keys()) {
        console.log(key); //0  1
    }
    
    for (let value of myMap.key()) {
        console.log(value); //  零  一
    }
    
    for (let [key, value] of myMap) {
        console.log(key + "=" + value);  //0=零   1=一
    }
    
  • forEach(callback, thisArg):

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

    其中:

    • 参数

      callback:必要,每个元素所要执行的函数。

      thisArg:可选,callback 执行时其 this 的值。

    • 返回值:undefined

    var myMap = new Map();
    myMap.set(0, "零");
    myMap.set(1, "一");
    myMap.forEach(function(value, key) {
        console.log(key + "=" + value);
    }, myMap)
    

(4)Map 对象的操作

  • Map 与 Array的转换

    var kvArray = [["key1", "value1"], ["key2", "value2"]];
     
    // Map 构造函数可以将一个 二维 键值对数组转换成一个 Map 对象
    var myMap = new Map(kvArray);
     
    // 使用 Array.from 函数可以将一个 Map 对象转换成一个二维键值对数组
    var outArray = Array.from(myMap);
    
  • Map 的克隆

    var myMap1 = new Map([["key1", "value1"], ["key2", "value2"]]);
    var myMap2 = new Map(myMap1);
     
    console.log(original === clone); 
    // 打印 false。 Map 对象构造函数生成实例,迭代出新的对象。
    
  • Map 的合并

    var first = new Map([[1, 'one'], [2, 'two'], [3, 'three'],]);
    var second = new Map([[1, 'uno'], [2, 'dos']]);
     
    // 合并两个 Map 对象时,如果有重复的键值,则后面的会覆盖前面的,对应值即 uno,dos, three
    var merged = new Map([...first, ...second]);
    
发布了77 篇原创文章 · 获赞 181 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_46124214/article/details/105145035