ECMAScript 6
新增Set集合类型,为这门语言带来集合数据结构。Set
在很多方面都像加强的Map,这是因为它们的大多数API和行为都是共有的。
6.6.1 基本API
-
使用
new
关键字和Set
构造函数可以创建一个空集合。如果想在创建的同时初始化实例,可以给Set
构造函数传入一个可迭代对象,其中需要包含插入到集合实例中的元素。const m = new Set(); // 使用数组初始化集合 const sl = new Set( [ "val1","val2","val3" ] ) console.log(sl.size); // 3 // 使用自定义迭代器初始化集合 const s2 = new Set({ [Symbol.iterator]: function* () { yield "val1"; yield "val2"; yield "val3" } }) console.log(s2); // Set { 'val1', 'val2', 'val3' }
-
初始化之后,可以使用
add()
增加值,使用has()
查询,通过size
取得元素数量,以及使用delete()和clear()
删除元素。 -
add()返回集合的实例,所以可以将多个添加操作连接起来,包括初始化。
const s = new Set(); console.log(s.has("Matt")); // false console.log(s.size); // 0 s.add("Matt").add("frisbie"); console.log(s.has("Matt")); // true console.log(s.size); // 2 s.delete("Matt"); console.log(s.has("Matt")); // false console.log(s.has("frisbie")); // true console.log(s.size); // 1 s.clear(); console.log(s.has("Matt")); // false console.log(s.has("frisbie")); // false console.log(s); // set {} const ss = new Set().add("vall"); ss.add("val2").add("val3"); console.log(ss); // Set { 'vall', 'val2', 'val3' }
-
与
Map
类似,set可以包含任何JavaScript
数据类型作为值,集合也使用SameValueZero
操作,基本上相当于使用严格对象相等的标准来检查值的匹配性。与严格相等一样,用作值的对象和其他集合类型在自己的内容或属性被修改时也不会改变。 -
add()和delete()操作是幂等的,delete()返回一个布尔值,表示集合中是否存在要删除的值。
const s = new Set(); const functionVal = function () { }; const symbolVal = Symbol(); const objectVal = new Object(); s.add(functionVal).add(symbolVal).add(objectVal); console.log(s.has(functionVal)); // true console.log(s.has(objectVal)); // true console.log(s); // Set { [Function: functionVal], Symbol(), {} } // 检查意味着独立的实例不会冲突 console.log(s.has(function () { })); // false const a = new Set(); const objVal = {}; const arrVal = []; a.add(objVal); a.add(arrVal); objVal.bar = "bar"; arrVal.push("bar"); console.log(a.has(objVal)); // true console.log(a.has(arrVal)); // true console.log(a); // Set { { bar: 'bar' }, [ 'bar' ] } const x = new Set(); x.add('foo'); console.log(x.size); // 1 x.add('foo'); console.log(x.size); // 1 console.log(x.delete('foo')); // true console.log(x.delete('foo')); // false
6.6.2顺序与迭代
-
Set
会维护值插入时的顺序,因此支持按顺序迭代。集合实例可以提供一个迭代器(Iterator),能以插入顺序生成集合内容。可能通过values()
方法及其别名方法keys()
,或者Symbol.iterator
属性,它引用values()
取得这个迭代器。 -
因为values()是默认迭代器,所以可以直接对集合实例使用扩展操作,把集合转为数组,集合的
entries()
方法返回一个迭代器,可以按照插入顺序产生包含两个元素的数组,这两个元素是集合中每个值的重复出现。const s = new Set(["val1","val2","val3"]); console.log(s.values === s[Symbol.iterator]); // true console.log(s.keys === s[Symbol.iterator]); // true for (let value of s.values()) { console.log(value); } // val1 // val2 // val3 for (let value of s[Symbol.iterator]()) { console.log(value); } // val1 // val2 // val3 console.log([...s]); // [ 'val1', 'val2', 'val3' ] for (let pair of s.entries()) { console.log(pair); } // ['val1', 'val1'] // ['val2', 'val2'] // ['val3', 'val3']
-
如果不使用迭代器,而是使用回调方式,则可以调用集合的
forEach()
方法并传入回调,依次迭代每个键值对。传入的回调接收可选的第二个参数,这个参数用于重写回调内部this的值。const s = new Set(["val1", "val2", "val3"]); s.forEach((val, dupVal) => console.log(`${val}->${dupVal}`)) // val1 - > val1 // val2 - > val2 // val3 - > val3 const s1 = new Set(["val1"]); // 字符串原始值作为值不会被修改 for (let value of s1.values()) { value = "newval"; console.log(value); // newval console.log(s1.has("val1")); // true } const valObj = {id:1} const s2 = new Set([valObj]); // 修改值对象的属性,但对象仍然存在于集合中 for (let value of s2.values()) { value.id = "newVal"; console.log(value); // { id: 'newVal' } console.log(s2.has(valObj)); // true } console.log(valObj); // { id: 'newVal' }
6.6.3定义正式集合操作
目前不太理解,故先不上任何描述文字和代码了。