概念
symbol是一种基本数据类型。类似于字符串的数据类型Symbol()函数可以接受一个字符串作为参数,表示对 Symbol 实例的描述Symbol值可以转为字符串和布尔值
注意
Symbol()函数前不能使用new命令- 相同参数的
Symbol函数的返回值是不相等的 Symbol值不能与其他类型的值进行运算Symbol值不能转为数值Symbol值作为对象属性名时,不能用点运算符
使用
description
const sym = Symbol('foo');
sym.description // "foo"
作为属性名的 Symbol
Symbol 值作为属性名时,该属性还是公开属性,不是私有属性。
在对象的内部,使用 Symbol 值定义属性时,Symbol 值必须放在方括号之中
let mySymbol = Symbol();
// 第一种写法
let a = {};
a[mySymbol] = 'Hello!';
// 第二种写法
let a = {
[mySymbol]: 'Hello!'
};
// 第三种写法
let a = {};
Object.defineProperty(a, mySymbol, { value: 'Hello!' });
// 以上写法都得到同样结果
a[mySymbol] // "Hello!"
属性名的遍历
Symbol 值作为属性名,遍历对象的时候,该属性不会出现在 for...in、for...of 循环中,也不会被 Object.keys()、Object.getOwnPropertyNames()、JSON.stringify() 返回。
Object.getOwnPropertySymbols() 可以获取指定对象的所有 Symbol 属性名。该方法返回一个数组,成员是当前对象的所有用作属性名的 Symbol 值。 Reflect.ownKeys(obj)
const obj = {};
const foo = Symbol('foo');
obj[foo] = 'bar';
for (let i in obj) {
console.log(i); // 无输出
}
Object.getOwnPropertyNames(obj) // []
Object.getOwnPropertySymbols(obj) // [Symbol(foo)]
为对象定义一些非私有的、但又希望只用于内部的方法。
Symbol.for() 和 Symbol.keyFor()
接受一个字符串作为参数,然后搜索有没有以该参数作为名称的 Symbol 值。如果有,就返回这个 Symbol 值,否则就新建一个以该字符串为名称的 Symbol 值,并将其注册到全局。
Symbol.keyFor() 方法返回一个已登记的 Symbol 类型值的 key
Symbol.for() 的这个全局登记特性,可以用在不同的 iframe 或 service worker 中取到同一个值。
const iframe = document.createElement('iframe');
iframe.src = String(window.location);
document.body.appendChild(iframe);
iframe.contentWindow.Symbol.for('foo') === Symbol.for('foo');
定义一组常量
const log = {};
log.levels = {
DEBUG: Symbol('debug'),
INFO: Symbol('info'),
WARN: Symbol('warn')
};
console.log(log.levels.DEBUG, 'debug message');
console.log(log.levels.INFO, 'info message');
const COLOR_RED = Symbol();
const COLOR_GREEN = Symbol();
function getComplement(color) {
switch (color) {
case COLOR_RED:
return COLOR_GREEN;
case COLOR_GREEN:
return COLOR_RED;
default:
throw new Error('Undefined color');
}
}
消除魔术字符串
const shapeType = {
triangle: Symbol()
};
function getArea(shape, options) {
let area = 0;
switch (shape) {
case shapeType.triangle:
area = .5 * options.width * options.height;
break;
}
return area;
}
getArea(shapeType.triangle, { width: 100, height: 100 });
单例模式
// mod.js
const FOO_KEY = Symbol('foo');
function A() {
this.foo = 'hello';
}
if (!global[FOO_KEY]) {
global[FOO_KEY] = new A();
}
module.exports = global[FOO_KEY];
内置的 Symbol 值
Symbol.hasInstance、Symbol.isConcatSpreadable、Symbol.species、Symbol.match、Symbol.replace、Symbol.search、Symbol.split、Symbol.iterator、Symbol.toPrimitive、Symbol.toStringTag、Symbol.unscopables