ES6里的Symbol到底有何用

322 阅读2分钟

首先,我们来看下错误的认识

使用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的应用场景永远是围绕着它的唯一性展开的,一句话总结:构建对象的不可变隐藏属性,避免冲突以及序列化。具体阐述如下:

  1. 没有两个Symbol值是相等的
  2. 使用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,无法访问,无法修改属性值