应用场景1:使用Symbol来作为对象属性名(key)
Symbol类型的key是不能通过Object.keys()或者for…in来枚举的,它未被包含在对象自身的属性名集合(property names)之中。所以,利用该特性,我们可以把一些不需要对外操作和访问的属性使用Symbol来定义。也正因为这样一个特性,当使用JSON.stringify()将对象转换成JSON字符串的时候,Symbol属性也会被排除在输出内容之外,我们可以利用这一特点来更好的设计我们的数据对象,让“对内操作”和“对外选择性输出”变得更加优雅。
应用场景2:使用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!"
应用场景3:使用Symbol定义类的私有属性/方法
使用它来定义的类属性是没有办法被模块外访问到的,可以达到了一个私有化的效果。
消除魔术字符串
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 });
总结:
用于创建独一无二的值,可做唯一key用于缓存等场景
用于创建类的私有变量,利用symbol属性不能被枚举的特性声明作为私有属性
用来重置对象的属性,比如 Symbol.toStringTag
可实现 Symbol.iterator迭代器, 让普通对象变为可迭代对象
使用Symbol.for(‘xxx’)获取全局的symbol值