Symbol
文章内容参考《ECMAScript 6 入门》。
概述
Symbol 是 ES6 引入的一种新的原始数据类型,是独一无二的值。
注意: Symbol 函数不能使用 new 命令,因为生成的 Symbol 是一个原始类型的值,不是对象。
JavaScript 的七种数据类型:
- Undefined
- Null
- Boolean
- String
- Number
- Object
- Symbol
判断数据类型的方法
1 | let data = Symbol() |
使用事项
- Symbol 是独一无二的值。
1 | let idx = Symbol('pro') |
- Symbol 函数可以接受一个字符串作为参数(如:例 1),表示对 Symbol 实例的描述,主要是为了在控制台显示,或者转为字符串时,比较容易区分。
1 | // 无法区分两者 |
- 当 Symbol 的参数是一个对象,就会调用该对象的 toString 方法(执行拆箱操作),将其转为字符串,然后才生成一个 Symbol 值。
1 | const obj = { |
- Symbol 值可以显式转为字符串和布尔值。但是不能转换成数值,也不能与其他类型的值进行运算,会报错。
- 转字符串
1 | let s = Symbol('Str Symbol') |
- 转布尔
1 | let s = Symbol('Str Symbol') |
- 转数值,运算
1 | let s = Symbol('Str Symbol') |
- Symbol 函数不能使用 new 命令,因为生成的 Symbol 是一个原始类型的值,不是对象。
1 | new Symbol() // TypeError: Symbol is not a constructor |
Symbol.prototype.description
创建 Symbol 的时候,可以添加一个描述。
1 | const s = Symbol('sym') |
上面代码中,s 的描述就是字符串 sym。
但是,读取这个描述需要将 Symbol 显式转为字符串,即下面的写法。
1 | const s = Symbol('sym') |
上面的用法不是很方便。ES2019 提供了一个实例属性 description,直接返回 Symbol 的描述。
1 | const s = Symbol('sym') |
Symbol 作为对象属性名
根据每一个 Symbol 值都是不等的特性,可以用 Symbol 作为唯一标识符,使用 Symbol 作为对象属性名可以保证不会出现同名的属性。
注意: symbol 不是字符串类型!!!
使用 symbol 作为对象属性名时,必须放在方括号 [ ]之 中,因为点运算符后面总是字符串。
1 | let mySymbol = Symbol(); |
使用 Symbol 来代替常量
我们经常需要用一组常量区分不同的类型,处理不同的逻辑。其实我们并不在意这几个常量值是什么,只要是唯一的。这时可以用 Symbol 来实现。
1 | const apple = 'myApple' |
观察以上代码,我们会发现,上述定义的常量值是什么并不重要。只要保证常量值间互不相等即可。
直接使用 Symbol 赋值即可:
1 | const apple = Symbol() |
Symbol 属性检索
以 Symbol 作为属性名,不会出现在 for…in、for…of 循环中,也不会被 Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()返回。
- Object.getOwnPropertySymbols 方法:获取指定对象的所有 Symbol 属性名的集合数组
1 | const a = Symbol('a') |
- Reflect.ownKeys 方法:返回所有类型的键名,包括常规键名和 Symbol 键名。
1 | let obj = { |
Symbol 定义类的私有属性/方法 (重点)
以 Symbol 值作为名称的属性,不会被常规方法遍历得到。利用这个特性,可以为对象定义一些非私有的、但又希望只用于内部的方法。
1 | function myObject(name, age) { |
Symbol 共享体系
如果想创建一个可共享的 Symbol,可以使用 Symbol.for()方法。
Symbol.for 方法,接收一个字符串参数,然后全局环境中搜索有没有以该字符串参数作为名称的 Symbol 值:
- 如果有,就返回这个 Symbol 值
- 否则就全局环境中登记新建并返回一个以该字符串为名称的 Symbol 值。
1 | let s1 = Symbol.for('s') |
注意: Symbol.for 为 Symbol 值登记的名字,是全局环境的,可以在不同的 iframe 或 service worker 中取到同一个值。
1 | iframe = document.createElement('iframe'); |
上面代码中,iframe 窗口生成的 Symbol 值,可以在主页面得到。
END
无论怎样,都别丢了快乐和努力。
转载分享,请标明出处。