首先,我们来看下错误的认识
使用Symbol来替代常量
凡是说应用场景,可以用Symbol来代替字符串作为常量的,都是错误的说法,比如下面这样的:
定义一组常量来代表一种业务逻辑下的几个不同类型,我们通常希望这几个常量之间是唯一的关系,为了保证这一点,我们需要为常量赋一个唯一的值,有了Symbol,直接就保证了常量的值是唯一的了
// 原写法,定义常量,被认为无法保证常量的唯一性
const BASIC = 'basic';
const SUPER = 'super';
// 通过Symbol改写如下
const tabTypes = {
basic: Symbol(),
super: Symbol(),
}
if (type === tabTypes.basic) {
return <div>basic tab</div>
}
if (type === tabTypes.super) {
return <div>super tab</div>
}
以上使用Symbol改写后,有啥用啊,啥作用都没有,type永远都不可能等于tabTypes.basic(或者等于tabTypes.super)
Symbol的应用场景永远是围绕着它的唯一性展开的,一句话总结:构建对象的不可变隐藏属性,避免冲突以及序列化。具体阐述如下:
- 没有两个Symbol值是相等的
- 使用Symbol值作为对象属性名 这样就相当于在这个对象上定义了一个唯一的属性名,并且外部无法直接通过for...of遍历得到属性名,或者通过Object.keys(),也是无法获取的,相当于私有属性。只能通过Object.getOwnPropertySymbols得到symbol数组
举例说明如下:
使用Symbol作为对象的属性名,可以确保唯一,无法从外部直接访问或替换覆盖这个属性名的值,因此可以作为私有属性使用。
function getObj() {
const foo = Symbol('foo');
const test = {
[foo]: 1,
name: 'test'
};
return test;
}
const a = getObj();
a[Symbol('foo')]; // undefined,无法访问,无法修改属性值