Symbol
Symbol 是一个原始值类型,Symbol()
函数会返回 symbol 类型的值,创建的值是唯一的。
用法
Symbol()函数可以接受一个字符串作为参数,表示对 Symbol 实例的描述。这主要是为了在控制台显示,或者转为字符串时,比较容易区分。
javascript
var sym1 = Symbol();
var sym2 = Symbol('foo'); // Symbol(foo)
Symbol('foo') === Symbol('foo'); // false
// 不支持 new 方法
var sym = new Symbol(); // TypeError
// 不支持与其他类型直接计算
'your symbol is ' + sym; // TypeError: can't convert symbol to string
注意
当使用 JSON.stringify() 时,以 symbol 值作为键的属性会被完全忽略:
javascriptJSON.stringify({ [Symbol('foo')]: 'foo' }); // '{}'
获取 Symbol
javascript
var obj = {};
var a = Symbol('a');
var b = Symbol('b');
obj[a] = 'Hello';
obj[b] = 'World';
var objectSymbols = Object.getOwnPropertySymbols(obj);
console.log(objectSymbols);
// [Symbol(a), Symbol(b)]
场景
- 作为属性名,避免命名冲突
- js 中没有私有属性、方法,可以用
Symbol
模拟出类似的效果。
简易实现
javascript
const genUniqueName = (function () {
let id = 0;
return function (description) {
return '@@' + description + '_' + id++;
};
})();
function SymbolPolyfill(description) {
if (this instanceof Symbol)
throw new TypeError('Symbol is not a constructor');
const symbol = {
toString() {
return this.__Name__;
}
};
Object.defineProperties(symbol, {
__Name__: {
value: genUniqueName(description),
writable: false,
configurable: false,
enumerable: false
},
__Description__: {
value: description,
writable: false,
configurable: false,
enumerable: false
}
});
return symbol;
}
var a = SymbolPolyfill('foo');
var b = SymbolPolyfill('foo');
console.log(a === b); // false
console.log(a.toString());
var o = {};
o[a] = 'hello';
o[b] = 'hi';
console.log(o); // Object { "@@foo_1": "hello", "@@foo_2": "hi" }