这是 ES6 中一种新的原始资料类型,表示独一无二的值,Symbol 的值通过Symbol
函数生成,可以保证不会与其他属性名或数值产生冲突,所以很适合用来代替传统定义常数内容值的方式。
let s = Symbol();typeof s // "symbol"// 定义常数内容值const ERROR = Symbol();const NOTICE = Symbol();const WARNING = Symbol();const CRITICAL = Symbol();
基本使用
Symbol 函数可以接受一个字串作为参数Symbol 值不能与其他类型的值进行运算Symbol 值可转成完全字串,使用toString()
方法,若有参数也会一同输出Symbol 值可作为物件中的属性名,使用中括号[]
,能防止此属性名(关键字)被改写或覆盖// 独一无二不会有任何相同的值,儘管接受的参数是相同的let s1 = Symbol('new');let s2 = Symbol('new');s1 === s2 // false// 可转成完全字串console.log(s1.toString()); // 'Symbol(new)'// 可作为物件中的属性名let obj = { [s1]: 'Hello!'};console.log(obj); // { Symbol(new): "Hello!" }
进阶使用
Symbol 作为属性名时,该属性不会出现在for...in
、for...of
迴圈迭代中,也不会在Object.keys()
、Object.getOwnPropertyNames()
等等之类的方法中被获取,只有唯一使用Object.getOwnPropertySymbols()
此方法才能获取拥有 Symbol 值的属性名。
let s1 = Symbol('s1');let s2 = Symbol('s2');const obj = { [s1]: 'Hello', [s2]: 'World'};for (let key in obj) { console.log(key); // 无输出}let propertyNames = Object.getOwnPropertyNames(obj);console.log(propertyNames); // []let propertySymbols = Object.getOwnPropertySymbols(obj);console.log(propertySymbols); // [ Symbol(s1), Symbol(s2) ]
应用:
Symbol 属性不会被常规方法获取,适合用在定义物件类别(class)中的非私有的、但又希望只用于内部的方法Symbol.for() & Symbol.keyFor()
Symbol.for()
: 可以重新使用同一个 Symbol 值,若定义时输入参数一样,则 Symbol 值会相等Symbol.keyFor()
: 可以取得在使用Symbol.for()
定义时所输入的参数值使用此 2 个函数方法来重複利用资源let s1 = Symbol.for('new');let s2 = Symbol.for('new');s1 === s2 // trueSymbol.keyFor(s1) // 'new'// 由于 Symbol() 是没有登记机制的,所以使用 .keyFor() 会无效let s3 = Symbol('new');Symbol.keyFor(s3) // undefined
Symbol.iterator
作为 ES6 iterator(迭代器)的建构方法名称,可参考: ES6 Iterators in Depth。