ES6--Set & Map

这个笔记是摘录一些 set & map 里面比较重要的知识点,没有特别细,需要先对语法有一些了解的再看,应该算是一个记忆的文档吧。
Set
1.向Set加入值的时候, 不会发生类型转换,所以 5"5"是两个不同的值。它类似于精确相等运算符( ===),主要的区别是 NaN等于自身,而精确相等运算符认为 NaN不等于自身。
2.新的数组去重的方法: [...new Set(array)]
3.另外两个对象始终是不相等的 
4.Set实例的方法分为两大类:操作方法(用于操作数据)和遍历方法(用于遍历成员)。
操作方法(用于操作数据):
  • add(value):添加某个值,返回Set结构本身。
  • delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
  • has(value):返回一个布尔值,表示该值是否为Set的成员。
  • clear():清除所有成员,没有返回值。
遍历方法(用于遍历成员):
  • keys():返回键名的遍历器
  • values():返回键值的遍历器
  • entries():返回键值对的遍历器
  • forEach():使用回调函数遍历每个成员

  需要特别指出的是,Set的遍历顺序就是插入顺序。这个特性有时非常有用,比如使用Set保存一个回调函数列表,调用时就能保证按照添加顺序调用。

  

5.这就提供了去除数组重复成员的另一种方法
   
 function dedupe(array) {
              return Array.from(new Set(array));
    }
 dedupe([1, 1, 2, 3]) // [1, 2, 3]

 

 

7.注意,rest参数之后不能再有其他参数(即只能是最后一个参数),否则会报错
8.扩展运算符 ...
   扩展运算符(spread)是三个点(...)。它好比rest参数的逆运算,将一个数组转为用逗号分隔的参数序列。
   扩展运算符( ...)内部使用 for...of循环,所以也可以用于Set结构。
    替代数组的apply方法 
       // ES5的写法 
     Math.max.apply(null, [14, 3, 77])
     // ES6的写法
     Math.max(...[14, 3, 77]) 
     // 等同于
    Math.max(14, 3, 77);
另一个例子是通过 push函数,将一个数组添加到另一个数组的尾部
// ES5的写法
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
Array.prototype.push.apply(arr1, arr2); 
// ES6的写法
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1.push(...arr2);

下面是另外一个例子。

// ES5
new (Date.bind.apply(Date, [null, 2015, 1, 1]))
// ES6
new Date(...[2015, 1, 1]);

9.运算符的扩展应用:

     合并数组
     与解构赋值结合     //   如果将扩展运算符用于数组赋值,只能放在参数的最后一位,否则会报错
     函数的返回值
     字符串
     实现了Iterator接口的对象
     Map和Set结构,Generator函数
10.严格模式
    从ES5开始,函数内部可以设定为严格模式。 《ECMAScript 2016标准》做了一点修改,规定只要函数参数使用了默认值、解构赋值、或者扩展运算符,那么函数内部就不能显式设定为严格模式,否则会报错。
11.name属性 
    需要注意的是,ES6对这个属性的行为做出了一些修改。如果将一个匿名函数赋值给一个变量,ES5的name属性,会返回空字符串,而ES6的name属性会返回实际的函数名。
     Function构造函数返回的函数实例, name属性的值为“anonymous”。
12.set 的遍历操作, 扩展运算符(...)内部使用for...of循环,所以也可以用于Set结构。 
    注意点:如果是用了set对象的返回的也是一个set对象
    map() / filter() / 并集 / 交集 / 差集 的使用
    如果想在遍历操作中,同步改变原来的Set结构,目前没有直接的方法,但有两种变通方法。一种是利用原Set结构映射出一个新的结构,然后赋值给原来的Set结构;另一种是利用 Array.from方法。
map

1.Object结构提供了“字符串—值”的对应,Map结构提供了“值—值”的对应,是一种更完善的Hash结构实现。如果你需要“键值对”的数据结构,Map比Object更合适。

2.对map操作方法和便利方法的总结:

    get set size has delete clear

  keys() values() entries() forEach()

3.可以是对象,数组 字符串true和布尔值true是两个不同的键。 

                 如果对同一个键多次赋值,后面的值将覆盖前面的值。
                 如果读取一个未知的键,则返回 undefined
                 注意,只有对同一个对象的引用,Map结构才将其视为同一个键。这一点要非常小心 
var map = new Map();
map.set(['a'], 555);
map.get(['a']) // undefined
上面代码的set和get方法,表面是针对同一个键,但实际上这是两个值,内存地址是不一样的,因此get方法无法读取该键,返回undefined。  

  

4.在ES6中,有三类数据结构原生具备Iterator接口:数组、某些类似数组的对象、Set和Map结构。
Symbol.iterator构造函数
    let arr = ['a', 'b', 'c'];
    let iter = arr[Symbol.iterator]();
    iter.next() // { value: 'a', done: false }
    iter.next() // { value: 'b', done: false }
    iter.next() // { value: 'c', done: false }
    iter.next() // { value: undefined, done: true }      
//这里有点类似match方法,下一个下一个知道比那里不到为止 

5.for ....of  

一个数据结构只要部署了Symbol.iterator属性,就被视为具有iterator接口,就可以用for...of循环遍历它的成员。也就是说,for...of循环内部调用的是数据结构的Symbol.iterator方法。

        const arr = ['red', 'green', 'blue'];
        let iterator  = arr[Symbol.iterator]();
        for(let v of arr) {
          console.log(v);      // red green blue
        }

         for(let v of iterator) {
          console.log(v);      // red green blue
        }

JavaScript原有的for...in循环,只能获得对象的键名,不能直接获取键值。ES6提供for...of循环,允许遍历获得键值。

可以代替forEach循环

        var arr = ['a', 'b', 'c', 'd'];
  
        for (let a in arr) {
          console.log(a); // 0 1 2 3
        }
        
        for (let a of arr) {
          console.log(a); // a b c d
        }
  1. for...of循环调用遍历器接口,数组的遍历器接口只返回具有数字索引的属性。这一点跟for...in循环也不一样 / for...of循环不会返回数组arr的foo属性。
  2. for...of 循环的几个缺点:
    1. 数组的键名是数字,但是for...in循环是以字符串作为键名“0”、“1”、“2”等等。
    2. for...in循环不仅遍历数字键名,还会遍历手动添加的其他键,甚至包括原型链上的键。 某些情况下,for...in循环会以任意顺序遍历键名。 总之,for...in循环主要是为遍历对象而设计的,不适用于遍历数组。

6.map 的forEach方法   

map.forEach(function(value, key, map) {

  console.log("Key: %s, Value: %s", key, value);

});

7.map和其他各个数据类型的转化

(1)Map转为数组

let myMap = new Map().set(true, 7).set({foo: 3}, ['abc']);
[...myMap]
// [ [ true, 7 ], [ { foo: 3 }, [ 'abc' ] ] ]

(2)数组转为Map

new Map([[true, 7], [{foo: 3}, ['abc']]])
// Map {true => 7, Object {foo: 3} => ['abc']}

(3)Map转为对象

如果所有Map的键都是字符串,它可以转为对象。

function strMapToObj(strMap) {
  let obj = Object.create(null);
  for (let [k,v] of strMap) {
    obj[k] = v;
  }
  return obj;
}

let myMap = new Map().set('yes', true).set('no', false);
strMapToObj(myMap)
// { yes: true, no: false }

(4)对象转为Map

function objToStrMap(obj) {
  let strMap = new Map();
  for (let k of Object.keys(obj)) {
    strMap.set(k, obj[k]);
  }
  return strMap;
}

objToStrMap({yes: true, no: false})
// [ [ 'yes', true ], [ 'no', false ] ]

(5)Map转为JSON

Map转为JSON要区分两种情况。一种情况是,Map的键名都是字符串,这时可以选择转为对象JSON。

function strMapToJson(strMap) {
  return JSON.stringify(strMapToObj(strMap));
}

let myMap = new Map().set('yes', true).set('no', false);
strMapToJson(myMap)
// '{"yes":true,"no":false}'

另一种情况是,Map的键名有非字符串,这时可以选择转为数组JSON。

function mapToArrayJson(map) {
  return JSON.stringify([...map]);
}

let myMap = new Map().set(true, 7).set({foo: 3}, ['abc']);
mapToArrayJson(myMap)
// '[[true,7],[{"foo":3},["abc"]]]'

(6)JSON转为Map

JSON转为Map,正常情况下,所有键名都是字符串。

function jsonToStrMap(jsonStr) {
  return objToStrMap(JSON.parse(jsonStr));
}

jsonToStrMap('{"yes":true,"no":false}')
// Map {'yes' => true, 'no' => false}

但是,有一种特殊情况,整个JSON就是一个数组,且每个数组成员本身,又是一个有两个成员的数组。这时,它可以一一对应地转为Map。这往往是数组转为JSON的逆操作。

function jsonToMap(jsonStr) {
  return new Map(JSON.parse(jsonStr));
}

jsonToMap('[[true,7],[{"foo":3},["abc"]]]')
// Map {true => 7, Object {foo: 3} => ['abc']}

完毕!

转载于:https://www.cnblogs.com/younger-plant/p/6075043.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值