本文是因为自己在 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 下面的值。
网友评论