ES6供应了新的数据构造Set,它相似与数组,然则成员值都是唯一的,没有反复的值。 Set自身是一个组织函数,用来天生Set数据构造。
const s = new Set();
[2,3,5,4,5,2,2].forEach(x=>s.add(x));
for(let i of s){
console.log(i);//2 3 5 4
}
上面代码经由过程add()要领向Set构造到场成员,效果表明Set构造不会增加反复的值。
Set函数能够接收一个数组作为参数,用来初始化。
//例子1
const set = new Set([1,2,3,4,4]);
[...set];//[1,2,3,4]
//例子2
const items = new Set([1,2,3,4,5,5,5,5]);
items.size//5
//例子3
const set = new Set(document.querySelectorAll('div'));
上面代码中,例一和例二都是Set函数接收数组作为参数,例三是接收相似数组的对象作为参数。
上面代码也展现了一种去除数组反复成员的要领。
//去除数组的反复成员
[...new Set(array)]
//去除字符串内里的反复字符
[...new Set('ababbc')].join('');//'abc'
//下面代码向Set实例增加了两个NaN,然则只能到场一个。这表明在Set内部两个NaN是相称。
let set = new Set();
let a = NaN;
let b = NaN;
set.add(a);
set.add(b);
set // Set {NaN}
//别的,两个对象老是不相称的。
let set = new Set();
set.add({});
set.size // 1
set.add({});
set.size // 2
Set实例的属性和要领
Set构造的实例有以下属性。
-Set.prototype.constructor:组织函数,默许就是set函数。
-Set.prototype.size:返回Set实例的成员总数。
Set实例的要领分为两大类:操纵要领和遍历要领。下面先引见四个操纵要领。
-add(value):增加某个值,返回Set构造自身。
-delete(value):删除某个值,返回一个布尔值,示意删除是不是胜利。
-has(value):返回一个布尔值,示意该值是不是为Set的成员。
-clear();消灭一切成员,没有返回值。
下面这些属性和要领的示例以下:
s.add(1).add(2).add(2);
//注重2被到场了两次
s.size//2
s.has(1)//true
s.has(2)//true
s.has(3)//false
s.delete(2);
s.has(2)//false
下面是一个对照,看看在推断是不是包含一个键上面,Object构造和Set构造的写法差别。
//对象的写法
const properties ={
'width':1,
'height':1
};
if(properties[someName]){
//do something
}
//Set的写法
const properties = new Set();
properties.add('width');
properties.add('height');
if(properties.has(someName)){
//do something
}
Array.from要领能够将Set构造转为数组。
const items = new Set([1,2,3,4,5]);
const array = Array.from(items);
这就供应了去除数组反复成员的另一种要领。
function dedupe(array){
return Array.from(new Set(array));
};
dedupe([1,1,2,3])//[1,2,3]
遍历操纵
Set 构造的实例有四个遍历要领,能够用于遍历成员。
-keys():返回键名的遍历器。
-values():返回键值的遍历器。
-entries():返回键值对的遍历器。
-forEach():运用回调函数遍历每一个成员。
(1)keys(),value(),entries()
keys要领、values要领、entries要领返回的都是遍历器对象。因为Set构造没有键名,只要键值所以keys要领和values要领的行动完整一致。
let set = new Set(['red','green','blue']);
for(let item of set.keys){
console.log(items);//red,grren,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']
上面代码中,entries要领返回的遍历器,同时包含键名和键值,所以每次输出一个数组,它的两个成员完整相称。
Set构造的实例默许可遍历,它的默许遍历器天生函数就是它的values要领。
Set.prototype[Symbol.iterator] === Set.prototype.values
这就意味着,能够省略values要领,直接用for…of轮回遍历Set。
let set = new Set(['red','green','blue']);
for(let x of set){
console.log(x);
}
//red green blue
(2)forEach()
Set构造的实例与数组一样,也具有forEach要领,用于对每一个成员实行某种操纵,没有返回值。
let set = new Set([1,4,9]);
set.forEach((value,key)=>console.log(key+':'+value))
//1:1 4:4 9:9
上面代码申明,foreach要领的参数就是一个处置惩罚函数。该函数的参数与数组的forEach一致,依次为键值、键名、鸠合自身。这里须要注重,Set构造的键名就是键值,因而第一个参数与第二个参数的值永远都是一样的。别的,forEach要领还能够有第二个参数,示意绑定处置惩罚函数内部的this对象。
(3)遍历的运用
扩大运算符(…)内部运用for…of轮回,所以也能够运用Set构造。
let set = new Set(['red','green','blue']);
let arr = [...set];
//['red','green','blue']
扩大运算符和Set构造相结合,就能够去除数组的反复成员。
let arr = [3,5,2,2,5,5];
let unique = [...new Set(arr)]
//[3,5,2]
而且,数组的map和filter要领也能够间接用于Set了。
let set = new Set([1,2,3]);
set = new Set([...set].map(x=x>*2));
//返回set构造:{2,4,6}
let set = new Set([1,2,3,4,5]);
set = new Set([...set].filter(x=>(x%2)==0));
//返回Set构造:{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}
Map寄义和基础用法
Javascript的对象,本质上是键值对的鸠合,然则传统上只能用字符串看成键,这给它的运用带来了很大的限定。
const data = {};
const element = document.getElementById('myDiv');
data[element] = 'metadata';
data['[object HTMLDivElement]']//'metadata'
上面代码原意是将一个DOM节点作为对象data的键,然则因为对象只接收字符串作为键名,所以element被自动转为字符串[object HTMLDivElement].
为了处理这个题目,ES6供应了Map数据构造。他相似与对象,也是键值对的鸠合,然则键的局限不限于字符串,各种类型的值都能够看成键。也就是说,Object构造供应了字符串-值的对应,Map构造供应了值-值的对应,是一种更完美的Hash构造完成。假如你须要键值对的数据构造,Map比Object更适宜。
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
上面代码运用Map构造set要领,将对象o看成m的一个键,然后又运用get要领读取这个键,接着运用delete要领删除这个键。
上面的例子展现了怎样向Map增加成员。作为组织函数,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
事实上,不仅仅是数组,任何具有Iterator接口、每一个成员都是一个双元素的数组的数据构造都克以看成Map组织函数的参数。也就是说,Set和Map都能够用来天生新的Map。
const set = new Set([
['foo',1],
['bar',2]
])
const m1 = new Map(set);
m1.get('foo')//1
const m2 = new Map([['baz',3]]);
const m3 = new Map(m2);
m3.get('baz')//3
上面代码中,我们离别运用set对象和Map对象,看成Map组织函数的参数,效果都天生了新的Map对象。
假如对同一个键屡次赋值,背面的值将掩盖前面的值。
const map = new Map();
map.set(1,'aaa')
.set(1,'bbb')
map,get(1)//'bbb'
上面代码对键1一连赋值两次,后一次的值掩盖前一次的值。
假如读取一个未知的键,则返回undefined。
new Map().get('dsada')//undefined.
实例的属性和操纵要领
(1)size属性
size属性返回Map构造的成员总数。
const map = new Map()
map.set('foo',true)
map.set('bar',false)
map.szie//2
(2)set(key,value)
set要领设置键名key对应的键值为value,然后返回全部map构造。假如key已经有值,则键值会被更新,不然就新天生该键。
const m = new Map()
m.set('edition',6);//键是字符串
m.set(262,'standard');//键是数值
m.set(undefined,'nah');//键是undefined
set要领返回的是当前的Map对象,因而克以采纳链式写法。
let map = new Map()
.set(1,'a')
.set(2,'b')
.set(3,'c')
(3)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
(4)has(key)
has要领返回一个布尔值,示意某个键是不是在当前Map对象当中。
const m = new Map();
m.set('edition',6);
m.set('262','standard');
m.set(undefined,'nah');
m.has('edition')//true
(5)delete(key)
delete要领删除某个键,返回true,假如删除失利,返回false。
const m = new Map();
m.set(undefined,'nah');
m.has(undefined)//true
m.delete(undefined);
m.has(undefined);//false
(6)clear()
clear要领消灭一切成员,没有返回值。
let map = new Map();
map.set('foo',true);
map.set('bar',false);
map.size//2
map.clear();
map.size//0;