一:Symbol
ES6 引入了一种新的原始数据类型Symbol
,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,前六种是:undefined
、null
、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。
对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的 Symbol 类型。凡是属性名属于 Symbol 类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。
1)Symbol 值通过Symbol
函数生成,而不是使用new
命令,否则会报错。
var s1 = Symbol(描述);
2)Symbol
函数的参数只是表示对当前 Symbol 值的描述,相同参数的Symbol
函数的返回值是不相等的:
var s1 = Symbol('foo');
var s2 = Symbol('foo'); s1 === s2 // false
3)使用:使用 Symbol 值定义属性时,Symbol 变量必须放在方括号之中被赋值,也即:symbol类型的内容作为属性名时,只能用[]来访问。
var mySymbol = Symbol();
var a = {};
a[mySymbol] = 'Hello!';
Symbol 值作为对象属性名时,不能用点运算符来调用,否则会把symbol作为了一个字符串类型的属性名,丧失了独一性:
var mySymbol = Symbol();
var a = {}; a.mySymbol = 'Hello!';//导致mysymbol转变成了字符串属性名
a[mySymbol] // undefined
a['mySymbol'] // "Hello!"
4)Symbol值作为属性名时的属性遍历
Symbol值作为属性名,该属性不会出现在for...in
、for...of
循环中,也不会被Object.keys()
、Object.getOwnPropertyNames()
、JSON.stringify()
返回。但是,有一个Object.getOwnPropertySymbols
方法,可以获取指定对象的所有 Symbol 属性名。
Object.getOwnPropertySymbols
方法返回一个数组,成员是当前对象的所有用作属性名的 Symbol 值。
5)使用同一个Symbol值:
Symbol.for
方法可以做到这一点。它接受一个字符串作为参数,然后搜索有没有以该参数作为名称的Symbol值。如果有,就返回这个Symbol值,否则就新建并返回一个以该字符串为名称的Symbol值。
var s1 = Symbol.for('foo');
var s2 = Symbol.for('foo'); s1 === s2 // true
Symbol.keyFor
方法返回一个已登记的 Symbol 类型值的key,即创建的时候的描述参数:
var s1 = Symbol.for("foo");
Symbol.keyFor(s1) // "foo"
二:Set
ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。
1)创建
s = new Set(参数);
2)操作
四个操作方法。
-
add(value)
:添加某个值,返回Set结构本身。 -
delete(value)
:删除某个值,返回一个布尔值,表示删除是否成功。 -
has(value)
:返回一个布尔值,表示该值是否为Set
的成员。 -
clear()
:清除所有成员,没有返回值。
3)遍历
四个遍历方法,可以用于遍历成员。
-
keys()
:返回键名的遍历器 -
values()
:返回键值的遍历器 -
entries()
:返回键值对的遍历器 -
forEach(回调函数)
:使用回调函数遍历每个成员
Set
的遍历顺序就是插入顺序。这个特性有时非常有用,比如使用Set保存一个回调函数列表,调用时就能保证按照添加顺序调用。
三:WeekSet
WeakSet 的成员只能是对象,而不能是其他类型的值。
WeakSet 中的对象都是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于 WeakSet 之中。
1)创建
const ws = new WeakSet(参数);//具有 Iterable 接口的对象,都可以作为 WeakSet 的参数
2)操作
WeakSet 结构有以下三个方法。
- WeakSet.prototype.add(value):向 WeakSet 实例添加一个新成员。
- WeakSet.prototype.delete(value):清除 WeakSet 实例的指定成员。
- WeakSet.prototype.has(value):返回一个布尔值,表示某个值是否在 WeakSet 实例之中。
四:Map
键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
1)创建
const map = new Map(......);
不仅仅是数组,任何具有 Iterator 接口、且每个成员都是一个双元素的数组的数据结构都可以当作Map
构造函数的参数。
2)操作
size
属性返回 Map 结构的成员总数。
set
方法设置键名key
对应的键值为value
,然后返回整个 Map 结构。如果key
已经有值,则键值会被更新,否则就新生成该键。【这里的key可以是任何对象】
get
方法读取key
对应的键值,如果找不到key
,返回undefined
。
has
方法返回一个布尔值,表示某个键是否在当前 Map 对象之中。
delete
方法删除某个键,返回true
。如果删除失败,返回false
。
clear
方法清除所有成员,没有返回值。
3)遍历
-
keys()
:返回键名的遍历器。 -
values()
:返回键值的遍历器。 -
entries()
:返回所有键值对的遍历器。 -
forEach(回调函数)
:遍历 Map 的所有键值对,用回调函数处理。
Map 的遍历顺序就是插入顺序。
4)与其它数据结构的相互转换
map转数组:使用扩展运算符(...
)
const myMap = new Map()
.set(true, 7)
.set({foo: 3}, ['abc']);
[...myMap]
// [ [ true, 7 ], [ { foo: 3 }, [ 'abc' ] ] ]
数组转map:数组传入 Map 构造函数,就可以转为 Map。
map转对象:Map 的键都是字符串,它可以转为对象:把map传给对象的构造函数,提取map中内容作为属性。
对象转map:遍历对象的属性,使用map.set(key,value)添加到map中
五:WeekMap
WeakMap
只接受对象作为键名(null
除外),不接受其他类型的值作为键名。
WeakMap
的键名所指向的对象是弱引用,不计入垃圾回收机制。
WeakMap 与 Map 在 API 上的区别主要是两个,一是没有遍历操作(即没有key()
、values()
和entries()
方法),也没有size
属性。
二是无法清空,即不支持clear
方法。因此,WeakMap
只有四个方法可用:get()
、set()
、has()
、delete()
。