快速了解下 ES6 Symbol 的用法

广告位

本文是因为自己在 Symbol 上用得不够6, 简单整理下为了让自已时不时可以看看,方便记忆。  除了讲概念,…

本文是因为自己在 Symbol 上用得不够6, 简单整理下为了让自已时不时可以看看,方便记忆。 

除了讲概念,还讲一些例子,从例子入门。 

00 背景

本文基本参考了阮一峰《Symbol》。该文更加全面,并且定时更新一些 ES10+ 的新知识点,大家可以上去看看。 

Symbol 为什么要存在?

ES5 的对象属性名都是字符串,这容易造成属性名的冲突。比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin 模式),新方法的名字就有可能与现有方法产生冲突。如果有一种机制,保证每个属性的名字都是独一无二的就好了,这样就从根本上防止属性名的冲突。

01 入门

ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,前六种是:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。

(1) 返回 ‘symbol’

let s = Symbol(‘test’)

typeof s     // ‘symbol’

(2) Symbol 生成的值都不相等 

let s1 = Symbol(‘test’)

let s2 = Symbol(‘test’)

s1 === s2     // false 

而且 Symbol 我们不用 new. 

(3) 若要相等, 利用 Symbol.for 

let s1 = Symbol.for(‘test’)

let s2 = Symbol.for(‘test’)

s1 === s2  // true 

(4) 返向获取 symbol 实例的 key,利用 Symbol.keyFor

let s1 = Symbol.for(‘test’)

let key = Symbol.keyFor(s1)  // ‘test’

(5) ES2019 上新加的 description 属性 

let s1 = Symbol(‘test’)

s1.description = ‘the description of test’

(6) 在对象上的应用 

let symGetName = Symbol(‘getName’)

let symAge = Symbol(‘age’)

let obj = {

    [symGetName](args) {

        …

    }, 

    [symAge]: 18        

}

这样写的好处就是在文件的外部,没有人可以改写这个方式和属性。 

一个重要的问题,for … in, for … of 以及其他的所有迭代器都不能遍历到 symbol 的属性。 如果一定要遍历,有对应的方式可以用。 

Object.getOwnPropertySymbols

(7) 枚举上的应用

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’);

    }

}

所有所有都是为了避免出现相同的 值。 

(8) 单例上的应用 

// mod.js

const FOO_KEY = Symbol.for(‘foo’);

function A() {

    this.foo = ‘hello’;

}

if (!global[FOO_KEY]) {

    global[FOO_KEY] = new A();

}

module.exports = global[FOO_KEY];

这样的好处是为了,在文件的外部改不了 global 下面的值。 

关于作者: yandaxia

为您推荐