
本文是由于自己在 Symbol 上用得不够6, 简单整理下为了让自已时不时可以看看,方便记忆。?
除了讲概念,还讲少量例子,从例子入门。?
本文基本参考了阮一峰《Symbol》。该文更加全面,并且定时升级少量 ES10+ 的新知识点,大家可以上去看看。?
Symbol 为什么要存在?
ES5 的对象属性名都是字符串,这容易造成属性名的冲突。比方,你使用了一个他人提供的对象,但又想为这个对象增加新的方法(mixin 模式),新方法的名字就有可能与现有方法产生冲突。假如有一种机制,保证每个属性的名字都是独一无二的就好了,这样就从根本上防止属性名的冲突。
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 下面的值。?