ECMA Script 6_Symbol() 唯一类型值声明函数_Symbol 数据类型
Symbol 数据类型
-
let s = Symbol(); typeof s; // "symbol"
是 ES6 继 Number,String,Boolean,Undefined,Null 之后引入的新数据类型
对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的 Symbol 类型。
Symbol
函数的参数只是表示对当前 Symbol 值的描述
-
let s1 = Symbol('foo'); let s2 = Symbol('bar'); s1 // Symbol(foo) s2 // Symbol(bar) s1.toString(); // "Symbol(foo)" s2.toString(); // "Symbol(bar)"
凡是属性名属于 Symbol 类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。
背景:
ES5 的对象属性名都是字符串,这容易造成属性名的冲突
如果有一种机制,保证每个属性的名字都是独一无二的就好了,这样就从根本上防止属性名的冲突。
- 原始数据类型
Symbol
表示独一无二的值。
它是 JavaScript 语言的第七种数据类型
Symbol 值可以显式转为字符串
Symbol 值可以显式转为布尔值
- Symbol 值不能与其他类型的值进行运算,会报错
即使 Symbol
函数参数相同,但是它们是不相等的。- Symbol 值 作为对象的属性时,只能用 [ ] 访问进行读写
在对象的内部,使用 Symbol 值定义属性时,Symbol 值必须放在方括号之中
-
let s = Symbol(); let obj = { [s]: function (arg) { ... } }; obj[s](123);
- 常量使用 Symbol 值最大的好处,就是其他任何值都不可能有相同的值了,因此可以保证上面的
switch
语句会按设计的方式工作 -
const COLOR_RED = Symbol(); const COLOR_GREEN = Symbol(); function getComplement(color) { switch (color) { case COLOR_RED: return COLOR_N: return COLOR_GREEN; case COLOR_GREERED; default: throw new Error('Undefined color'); }; };
- 消除魔术字符串的方法,就是把它写成一个变量
-
const shapeType = { triangle: Symbol(), }; function getArea(shape, options) { let area = 0; switch (shape) { case shapeType.triangle: area = .5 * options.width * options.height; break; }; return area; }; getArea(shapeType.triangle, { width: 100, height: 100 });
- Symbol 作为属性时,非私有属性,遍历法
- Symbol 作为属性名,该属性不会出现在
for...in
、for...of
循环中,也不会被Object.keys()
、Object.getOwnPropertyNames()
、JSON.stringify()
返回 - 但是,它也不是私有属性,有一个
Object.getOwnPropertySymbols()
获取指定对象的所有 Symbol 属性名。 - 重新使用同一个 Symbol 值,Symbol.for('aName')
接受一个字符串作为参数,然后搜索有没有以该参数作为名称的 Symbol 值。
- 如果有,就返回这个 Symbol 值
- 否则就新建并返回一个以该字符串为名称的 Symbol 值
-
let s1 = Symbol.for('foo'); // 登记在全局环境中供搜索 let s2 = Symbol.for('foo'); // 登记在全局环境中供搜索 s1 === s2 // true
Symbol.for()
与Symbol()
这两种写法,都会生成新的 Symbol。
它们的区别是:
前者会被登记在全局环境中供搜索,后者不会。
Symbol.for()
不会每次调用就返回一个新的 Symbol 类型的值,而是会先检查给定的key
是否已经存在,如果不存在才会新建一个值。
比如,如果你调用Symbol.for("cat")
30 次,每次都会返回同一个 Symbol 值,
但是调用Symbol("cat")
30 次,会返回 30 个不同的 Symbol 值
Symbol.keyFor
() 返回一个已登记的 Symbol 类型值的key,即 Symbol.for() 生成的 Symbol 值
注意: 为 Symbol 值登记的名字,是全局环境的,可以在不同的 iframe 或 service worker 中取到同一个值
-
let obj = { [Symbol('my_key')]: 1, enum: 2, nonEnum: 3 }; Reflect.ownKeys(obj); // ["enum", "nonEnum", Symbol(my_key)]
--------小尾巴
________一个人欣赏-最后一朵颜色的消逝-忠诚于我的是·一颗叫做野的心.决不受人奴役.怒火中生的那一刻·终将结束...