本文是因为自己在 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 下面的值.
来源: http://www.mzh.ren/110e4544fd0d.html