ES6 Set、Map

Set

ES6提供了新的数据结构Set。它类似于数组。但是成的值都是唯一的,没有重复的值。
Set本身是一个构造函数,用来生成Set数据结构。
可以用来数组的去重。
向Set加入值的时候,不会发生类型的转换,所以5和‘5’是两个不同的值。Set内部 判断两个值是否不同使用的算法类似于精确相等运算符(===),于‘===’的主要的区别的NaN等于自身 而‘===’ NaN是不等于自身的。
对象基于指针问题 是不会相等的。

const s = new Set();
[2,3,4,5,6,4,3,4,2,2].forEach(x => s.add(x));
for(let i of s){
  console.log(i);
}
//2,3,4,5,6
const set = new Set([1,2,3,4,4])
[...set]
//1,2,3,4

let set = new Set();
let a = NaN;
let b = NaN;
set.add(a);
set.add(b);
set //Set{NaN};

Set实例的属性和方法
Set.prototype.constructor //指向本身
Set.prototype.size //Set实例的成员总数

方法:

add() //增加
delete() //删除
has() //查询 返回Boolean
clear() //清除所有

遍历方法:

keys()//返回键名
values()//返回键值
entries()//返回键值对数组
forEach() //loop
由于Set结构没有键名,只有键值所以keys和values方法的行为完全一致。

let set = new Set(['red', 'green', 'blue']);
for(let item of set.keys()){
  console.log(item);
// red
// green
// blue
}
for(let item of set.values()){
  console.log(item);
// red
// green
// blue
}
for(let item of set.entries()){
  console.log(item);
// ["red", "red"]
// ["green", "green"]
// ["blue", "blue"]
}
//所以set的value获取直接可以用for...of获取
for(let item of set){
  console.log(item);
// red
// green
// blue
}
//Set结构的实例于数组一样,也拥有forEach方法,用于对每个成员执行某种操作,没有返回值
set.forEach((key,value) => {console.log(key + ' : ' + value)});
// red:red
// green:green
// blue:blue
运用扩展运算符
let set = new Set(['red', 'green', 'blue']);
[...set]
//['red','green','blue']
//扩展运算符与Set结构相结合,就可以去除数组的重复成员
let set = [1,2,3,3,3,3,4,4,5];
[...new Set(set)]
//[1,2,3,4,5]
new Set([...set].filter(x => {return x % 2 === 0}));
//{2,4}
Set 实现并集/交集/差集
let a = new Set([1,2,3]);
let b = new Set([4,3,2]);
//并集
let union = new Set([...a,...b]);
//Set{1,2,3,4}
//交集
let intersect = new Set([...a].filter(x => b.has(x)));
//Set{2.3}
//差集
let difference = new Set([...a].filter(x => !b.has(x)));
//Set{1}
改变Set值
let set = new Set([1,2,3]);
set = new Set([...set].map(x => x*2));
//Set{2,4,6}
set = new Set(Array.from(set,x => x * 2));
//Set{2,4,6}

WeakSet

WeakSet结构与Set相似,也是不重复的值的集合。但是它与Set有两个区别。
首先WeakSet的成员只能是对象,而不能是其他类型的值。其中的对象都是弱引用,随时可能小时,跟浏览器垃圾回收机制有关。不会出现内存泄漏。
比较适合临时存放一组对象,以及存放跟对象绑定的信息。
方法:add() delete() has()
WeakSet不可遍历所以也没有size属性

const ws = new WeakSet();
ws.add(1)
//TypeError:Invalid value used in weak set
ws.add(Symbol());
//TypeError:Invalid value used in weak set

具有Iterable接口的对象,都可以作为WeakSet的参数。
b数组的成员为WeakSet的成员,而不是b数组本身。这意味着,数组的成员只能是对象。

const a = [[1,2],[3,4]];
const ws = new WeakSet(a);
//WeakSet{[1,2],[3,4]}
const b = [1,2];
const ws = new WeakSet(b);
//uncaught TypeError:Invalid value used in weak set;

Map

Javascript的对象(Object),本质上是键值对的集合(Hash结构),但是传统上只能用字符串当作键。
Map数据结构类似于对象,也是键值对的集合,但是与对象的区别是的繁为不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说Object结构提供了‘字符串-值’的对象,Map结构提供了‘值-值’的对象。这是一种更完善的Hash结构实现。如果你需要‘键值对’的数据结构,Map比Object更合适。

属性:size 返回Map结构的成员总数
方法:set get has delete clear
//Map结构数据的增删改查。
const m = new Map();
const o = {p:'hello world'};
m.set(o,'content');
m.get(o)//content
m.has(o)//true
m.delete(o)//true
m.has(o)//false
m.clear();
m.size //0
遍历的方法 keys values entries forEach
//Map数据结构可以接受一个数组作为参数。该数组的成员是一个个表示键值对的数组。
const map = new Map([
  ['name', '张三'],
  ['title', 'Author']
]);
map.size //2
map.has('name')//true
map.get('name')//'张三'
map.has('title')//true
map.get('title')//'Author'

//上面的例子解析执行的方法
const items = [
  ['name', '张三'],
  ['title', 'Author']
]

const map = new Map()
items.forEach(([key,value]) => map.set(key,value))
Set和Map都可以用来生成新的Map
const set = new Set([
  ['foo',1],
  ['bar',2]
]);
const m1 = new Map(set);
m1.get('foo')//1
const m2 = new Map([['bar',3]]);
const m3 = new Map(m2);
m3.get('bar')//3
m3.set('bar',4)
m3.get('bar')//4    如果对同一个键多次赋值,后面的值将覆盖前面的值

new Map().get('sdfsdf')//undefined

//如果键为对象要确定为同一个对象的引用
const map = new Map()
map.set(['a'],555);
map.get(['a']);//undefined

//同理,同样的值的两个实例,在Map结构中被视为两个键
const map = new Map()
var a = ['a'];
var b = ['a']
map.set(a,555);
map.set(b,666)
map.get(a);//555
map.get(b);//666

Map通过严格相等来判断是否为一个键。

0 === -0//true
true === 'true' //false
undefined === null //false
NaN === NaN //false   虽然NaN不严格相等于自身,但Map将其视为同一个键

Map与其他数据结构的互相转换

Map转为数组
const map = new Map([
  ['F', 'no'],
  ['T',  'yes'],
]);
[...map]
数组转为Map
new Map([...map])
Map转为对象
function Maptoobj(v){
  var obj = Object.create(null);
  for(let [key,value] of v){
    obj[key] = value
  }
  return obj
}
Maptoobj(map);
对象转化为Map
function objtomap(v){
  var map = new Map();
  for(let i of Object.keys(v)){
    map.set(i,v[i])
  }
  return map
}
objtomap({'a':1})
Map 转化为Json 如果Map的键名都是字符串
function maptojson(v){
  return JSON.stringify(Maptoobj(v))
}
let myMap = new Map().set('yes', true).set('no', false);
maptojson(myMap)
// '{"yes":true,"no":false}'
如果Map的键名有非字符串
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"]]]'
JSON转化为Map
function jsonToStrMap(jsonStr) {
  return objtomap(JSON.parse(jsonStr));
}

jsonToStrMap('{"yes": true, "no": false}')
// Map {'yes' => true, 'no' => false}
如果整个json是一个数组且每个数组成员本身又是一个又两个成员的数组
function jsonToMap(jsonStr) {
  return new Map(JSON.parse(jsonStr));
}

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

WeakMap

与Map数据结构类似,也是用于生成键值对的集合 与Weakset一样突出弱引用的作用。
与Map的区别
1.和WeakSet一样只接受对象作为键名(null除外,null为对象 但是null不可以作为键名),不接受其他类型的值作为键名。

const map = new WeakMap();
map.set(1,2)
//TypeError :1 is not an Object!
map.set(Symbol(),2)
//TypeError:Invalid value used as weak map key
map.set(null,2)
//TypeError:invalid value used as weak map key

与WeakSet一样 WeakMap没有遍历操作(即没有keys() values() entries()方法)也没有size属性。也不支持clear()方法。

const wm = new WeakMap()
wm.size //undefined
wm.clear//undefined
wm.forEach//undefined
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335