ES6-15【map与set】

一.概述

(1).map/set

set是一个成员唯一的数组map是一个对象

var set = new Set();
var map = new Map();

(2).降级

这四个无法通过babel降级

const map = new Map();
const set = new Set();
const p = new Promise();
const p1 = new Proxy();

二.set

(1).简述

var set = new Set();
console.log(set);

类似于数组的解构

(2).set方法

add方法添加数据

方法1
var set = new Set();
set.add(5);
set.add(7);
log(set);
Set(2){5,7}
[[Entries]]:Array(2)
0:5
1:7
length:2

方法2
var set = new Set([5,7])//里面的参数必需是支持迭代器接口的数据

成员必需唯一
var set = new Set([1,2,3,4,5,5,5,5]);
log(set);//这样也只输出[1,2,3,4,5]

不会隐式转换包括nan也是相等的
var set = new Set([undefined,undefined,null,null,5,'5',true,1,NaN,NaN,{},{}])
log(set)
[[Entries]]:Array(7)
0:undefined
1:null
2:5
3:"5"
4:true
5:1
6:NaN
7:value:{}
8:value:{}
length:9
对象由于引用不同所以不会合并,数组同理

添加两个对象,但是如果这么赋值的话,拿的其实是同一个引用
var x = {id:1},
    y = {id:2}
    set.add(x);
    set.add(y);
    set.add(x);
console.log(set);
[[Entries]]
0:object
1:object
length:2    


因为添加值返回的是set结构本身,所以可以链式调用
var x = {id:1},
    y = {id:2}
    set.add(x).add(y).add(x)

获得长度

var x = {id:1},
    y = {id:2}
    set.add(x)
        .add(y)
        .add(x);
console.log(set.size);//2    

删除

set.delete(y);//成功返回true 失败返回false
set.clear();//clear清空,返回值undefined

是否存在指定成员

log(set.has(x))//返回为true

与Obj的区别

var obj = {a:1,b:2}
log(obj)//{a:1,b:2}
detete obj.a
log(obj)//{b:2}

//虽然先log后删除/清空但是set也是提升了
log(set)
set.clear()
[[Entries]]:Array(0)
length:0

log(set);
set.delete(y);
[[Entries]]:Array(1)
0:Object
length:1

keys values entries

let set = new Set([1,2,3,4,5,6,7]);
//set没有键
log(set.keys());
[[Entries]]:Array(7)
0:1
1:2
3:4
4:5
5:6
6:7
length:7


log(set.values());
//SetIterator{1,2,3,4,5..}

log(set.entries());
//SetIterator{1,2,3,4,5..}

有迭代器方法next/也就是说可以for of
for(let i of set.Keys()){
    log(i)
}
//1 2 3 4 5 6 7

for(let i of set.values()){
    log(i)
}
//1 2 3 4 5 6 7

for(let i of set.entries()){
    log(i)
}
//
["1","1"]
["2","2"]
["3","3"]
["4","4"]
["5","5"]
["6","6"]
["7","7"]

因为通过迭代器直接访问的就是values,所以可以直接循环set
console.log(Set.prototype[Symbol.iterator] === Set.prototype.values);//true
for(let i of set){
    log(i)
}
1 2 3 4 5 6 7

foreach

let set = new Set(['a','b','c','d','e','f','g'];
set.forEach(function(value,keys,arr)){
    log(value,keys,arr)
}
a a {'a','b','c','d','e','f','g'}
b b {'a','b','c','d','e','f','g'}
c c {'a','b','c','d','e','f','g'}
d d {'a','b','c','d','e','f','g'}
....
也就是说第三个值不是数组本身了所以第三个参数不应该是arr应该是set

es6的书写方式
set.forEach((value,keys,arr) => console.log(value,keys,arr));

拓展运算符的支持

let set = new Set(['a','b','c','d','e','f','g'];
log(...set);
//a b c d e f g

去重
let set = new Set(['a','b','c','d','e','f','g'];
log([...set]);
去重最简单的方式就是收集到set当中,再展开到一个数组里

操作set结构成员

let set = new Set([1,2,3,4,5,6,7])
let set1 = new Set([...set].map(value => value *2));

难点

var arr = [1,2,3,4]
var arr1 = arr.map(parseInt);
log(arr1);//[1,NaN,NaN,NaN]
原理就是map里的参数 value, index
var arr1 = arr.map((value,idx)=> log(value,idx))
1 0
2 1
3 2
4 3
那么就代表着
parseInt(1,0)parseInt(2,1)parseInt(3,2)parseInt(4,3)

let set2 = new Set([[...set].map(parseInt)]);
log(set2);
0:1
1:NaN
....

与filter结合

let set2 = new Set([...set].filter(x => (x%2) == 0))
log(set2);//{2,4,6}

交集并集差集

并集
let a = new Set([1,2,3]);
let b = new Set([4,3,2]);
let union = new Set([...a,...b]);
log(union);

交集
let intersect = new Set([...a].filter(x => b.has(x)));

差集
let difference = new Set([...a].filter(x => !b.has(x)));

映射出一个结构

通过form方法拿到值且和map操作一致

let set = new Set([1,2,3]);
let set1 = new Set(Array.from(set,value=>value*2))

三.map

(1).与对象对比

当键名为对象的时候就会tostring,并不能实现键名-键值一一对应

var m = {}
    x = {id:1}
    y = {id:2}
m[x] = "foo"
m[y] = "bar"
log(m)//{[object Object]:"bar"}
log(m[x])//bar
log(m[y])//bar    
因为键名是对象的时候会tostring所以会产生覆盖的问题

(2).map

就能解决键名是对象的问题

let m = new Map();
var x = {id:1},
    y = {id:2}
m.set(x,'foo');
m.set(y,'bar');
log(m.get(x));//foo
log(m.get(y));//bar
//这样就可以了    

let m = new Map([1,2,3,4,5]);//同样需要参数是要具备iterator接口的,但是这样申明
是错误的,因为无法体现键值对所以要传入二元数组
let m = new Map([['name','zhangsan'],['title','lisi']])
log(m)

键名相同会覆盖
const map = new Map();
map.set(1,'foo')
map.set(1,'bar')
Map(1){1 >= "bar"}

(3).map方法

增加

let m = new Map();
m.set('name','zhangsan');
m.set('title','lisi');
log(m)
[[Entries]] Array(2)
0:{"name" => "zhangsan"}
1:{"name" => "lisi"}
length:2

底层传参实现代码

var items = [['name','wagwu'],['title','zhaoliu']]
let m = new Map();
items.forEach(([key,value]) => m.set(key,value))

获取

键名是数组的情况
const map = new Map();
map.set([5],555);
log(map.get([5]))//undefined
map.set({},555);
log(map.get({}))//undefined

访问没有定义的
输出undefiend
这样都是两个不同的引用值,没有公用指针


特殊获取
const map = new Map();
map.set(-0,123);
log(map.get(+0)) //123

map.set(undefined,1)
map.set(null,2)
log(map.get(undefined));//1
log(map.get(null));//2

map.set(NaN,123);
log(map.get(NaN));//123

与Set的方法区别就是

map中增加是set  set 中是add

map中还多了get

其余方法使用都与set相同

size

var x = {id:1},
    y = {id:2}
m.set(x,"foo")
m.set(y,"bar")   
log(m.size);//2 

delete

返回值为true

clear

返回值为undefined

has

返回值为true

set

返回值为原数组

也就说可以链式操作

keys values entries

var x = {id:1},
    y = {id:2}
m.set(x,"foo")
m.set(y,"bar") 

for(let keys of m.keys()){
    log(keys)
}
{id:1}
{id:2}

for(let keys of m.values()){
    log(values)
}
foo
bar

for(let keys of m.entries()){
    log(entries)
}
[{...},'foo']
[{...},'bar']

for of 直接迭代,map

log(m[Symbol.iterator] === m.entries)//true 所以直接调用map实例化对象 和entries一致
for(let [key,values] of m){
    log(key,values)
}
{id:1}"foo"
{id:2}"bar"

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值