Open ChuChencheng opened 4 years ago
ES6 引入了一种新的原始数据类型 Symbol
Symbol
目前有 7 种原始类型, 1 种引用类型
原始类型:
引用类型 Object
toString
for...in
for...of
Object.keys()
Object.getOwnPropertyNames()
JSON.stringify()
let sym = Symbol() const str = `some str with ${sym}` // TypeError: Cannot convert a Symbol value to a string String(sym) // 'Symbol()' sym.toString() // 'Symbol()'
let sym = Symbol() Boolean(sym) // true Number(sym) // TypeError sym + 2 // TypeError
如果传给 Symbol 的参数是一样的,生成的 Symbol 并不是同一个 Symbol :
Symbol('abc') === Symbol('abc') // false
传入的参数是作为 Symbol 的一个描述。
如果要获取这个描述,有两种方法:
Symbol('abc').toString() // 'Symbol(abc)'
Symbol('abc').description // 'abc'
使用 Symbol 作为 key 可保证不出现同名属性,导致对象属性被覆盖。
用于定义一组常量,例如:
const logLevel = { DEBUG: Symbol('debug'), INFO: Symbol('info'), WARN: Symbol('warn'), }
在上述常量中,我们其实并不关心 logLevel.DEBUG 具体是什么值,只需要保证其唯一就行,因此可以用 Symbol 来保证其中的属性值都不相等。有点类似 TypeScript 中的枚举 enum ,在编写代码时,我们不关心 enum 里面具体的值是什么,在运行时会自动编译成 1, 2, 3 这些在枚举中唯一的值。
logLevel.DEBUG
Symbol 值作为对象 key ,不会被常规方法遍历到,除非用 Object.getOwnPropertySymbols 这类方法,因此可以用 Symbol 来定义一些一定程度上私有的内部方法:
Object.getOwnPropertySymbols
let size = Symbol('size'); class Collection { constructor() { this[size] = 0; } add(item) { this[this[size]] = item; this[size]++; } static sizeOf(instance) { return instance[size]; } } let x = new Collection(); Collection.sizeOf(x) // 0 x.add('foo'); Collection.sizeOf(x) // 1 Object.keys(x) // ['0'] Object.getOwnPropertyNames(x) // ['0'] Object.getOwnPropertySymbols(x) // [Symbol(size)]
Symbol.for() 接受一个字符串参数,返回在全局环境中已经注册的 Symbol ,如果没有找到,则新建一个 Symbol
Symbol('abc') === Symbol('abc') // false Symbol.for('def') === Symbol.for('def') // true { let s = Symbol('sss') s === Symbol.for('sss') // false }
Symbol.keyFor() 返回一个已登记的 Symbol 类型的 key ,与 Symbol.description 类似
Symbol.description
let s1 = Symbol.for("foo"); Symbol.keyFor(s1) // "foo" let s2 = Symbol("foo"); Symbol.keyFor(s2) // undefined
Symbol.for() 这个方法是在全局登记的,因此可以跨 iframe 或 service worker 取到同一个 Symbol 值。
Symbol.for()
Symbol 相关的内容太多,这边不再列了。
http://es6.ruanyifeng.com/#docs/symbol
新的原始类型 Symbol
ES6 引入了一种新的原始数据类型
Symbol
目前有 7 种原始类型, 1 种引用类型
原始类型:
引用类型 Object
Symbol 特性
Symbol
函数生成,不能使用 new 命令toString
方法for...in
,for...of
,Object.keys()
,Object.getOwnPropertyNames()
,JSON.stringify()
遍历到或返回。类型转换
参数值
如果传给
Symbol
的参数是一样的,生成的 Symbol 并不是同一个 Symbol :传入的参数是作为 Symbol 的一个描述。
如果要获取这个描述,有两种方法:
Symbol('abc').toString() // 'Symbol(abc)'
Symbol('abc').description // 'abc'
应用
作为对象唯一键值
使用 Symbol 作为 key 可保证不出现同名属性,导致对象属性被覆盖。
作为常量
用于定义一组常量,例如:
在上述常量中,我们其实并不关心
logLevel.DEBUG
具体是什么值,只需要保证其唯一就行,因此可以用 Symbol 来保证其中的属性值都不相等。有点类似 TypeScript 中的枚举 enum ,在编写代码时,我们不关心 enum 里面具体的值是什么,在运行时会自动编译成 1, 2, 3 这些在枚举中唯一的值。定义非私有,但希望只用于内部的方法
Symbol 值作为对象 key ,不会被常规方法遍历到,除非用
Object.getOwnPropertySymbols
这类方法,因此可以用 Symbol 来定义一些一定程度上私有的内部方法:Symbol.for() 与 Symbol.keyFor()
Symbol.for() 接受一个字符串参数,返回在全局环境中已经注册的 Symbol ,如果没有找到,则新建一个 Symbol
Symbol.keyFor() 返回一个已登记的 Symbol 类型的 key ,与
Symbol.description
类似Symbol.for()
这个方法是在全局登记的,因此可以跨 iframe 或 service worker 取到同一个 Symbol 值。Symbol 相关的内容太多,这边不再列了。
参考
http://es6.ruanyifeng.com/#docs/symbol