基本语法
ES6新增一种数据类型:
Undefined
Null
Boolean
String
Number
Object
Symbol
Symbol
主要负责解决同名属性的区分。比如一个对象使用了另一个对象,而两个对象都有一个相同名称的属性,这时就引入Symbol
加以区分。
1 | let s = Symbol(); |
生成的Symbol是一个原始类型的值。可以把它当做是一个类似字符串的数据类型。
Symbol
接收一个参数,负责对Symbol实例的描述。而且,相同描述的Symbol实例实质是不相等的。
1 | var s1 = Symbol(); |
Symbol值可以显式转化为字符串或者布尔值。
作为属性名的Symbol
1 | var mySymbol = Symbol(); |
应用场景
Symbol
用于构造对象内部的私有属性比较合适,并且这种属性不会被for...in
或者Object.keys()
所选出。
1 | var size = Symbol('size'); |
Symbol.for()
接收一个字符串作为参数,返回以此字符串定义的Symbol对象。如果没有就新建一个对象并返回。
1 | var s1 = Symbol.for("foo"); // 新建Symbol("foo")对象 |
因此,调用两次Symbol("foo")
返回的对象不会相等,而调用两次Symbol.for("foo")
返回的对象一定相等。
对于参数的解析,ES6内部是通过调用toString
来进行,因此会有以下的解析结果。
1 | var a = Symbol.for(1); |
内置的Symbol值
Symbol.hasInstance
这是一个类的属性,foo instanceof Foo
实际调用Foo[Symbol.hasInstance](foo)
。
Symbol.isConcatSpreadable
对象的一个属性,为布尔值类型,表示该对象使用Array.prototype.concat()
时是否可以展开。
1 | let obj = {length: 2, 0: 'c', 1: 'd'}; |
还记得数组那章节里说有类似数组的对象,所以这里也可以将类数组对象的可展开属性设置为true
。
1 | let obj = {length: 2, 0: 'c', 1: 'd'}; |
但是经过测试,对于那些无法转成数组的对象,强行设置属性成为true
的时候往往不起作用。
1 | var obj = {name: "david", age: 16}; |
对于一个类来说,Symbol.isConcatSpreadable
属性必须写成一个返回布尔值的方法。
1 | class A1 extends Array { |
Symbol.iterator
对象的Symbol.iterator
属性,指向该对象的默认遍历器方法,即该对象进行for...of
循环时,会调用这个方法,返回该对象的默认遍历器。
1 | class Collection { |
Symbol.toPrimitive
在对象被转为原始类型的值时,会调用这个方法。
1 | var obj = { |
上面case when
中定义了一个default判断,如果没有这个判断,则会返回undefined
。
Symbol.toStringTag
这个属性可以用来定制调用Object.prototype.toString
方法时,[object Object]
或[object Array]
中object
后面的那个字符串。
1 | ({[Symbol.toStringTag]: 'Foo'}.toString()) |
Symbol.unscopables
对象的Symbol.unscopables
属性,指向一个对象。该对象指定了使用with
关键字时,哪些属性会被with
环境排除。
1 | Array.prototype[Symbol.unscopables] |