ES6篇 - Symbol
Symbol
ES6 新增的一种原始数据类型;
Symbol 值是独一无二的, 基于此特性, Symbol 值通常作为对象的属性名使用, 从根本上防止属性名的冲突;
Symbol 值不能与其他类型的值进行运算, 它可以显式转为字符串(.toString()
), 也可转为布尔值, 但不能转为数值, 因此不能做运算操作;
Symbol 创建
Symbol 值通过 Symbol() 函数生成;
Symbol() 函数不能使用 new 命令, 因为生成的 Symbol 是一个原始类型的值, 不是对象, 其不能添加属性;
Symbol() 函数可接受一个字符串作为参数, 该字符串用于表示 Symbol 实例的描述, 便于 Symbol 值的区分;
1 |
|
Symbol 实例的描述可以通过显示转为字符串或通过 ES2019 提供的实例属性 Symbol.prototype.description
获得, sym.description
可以直接返回 Symbol 的描述;
1 |
|
Symbol 用作对象属性名
好处: 保证对象不会出现同名属性, 避免属性被改写或覆盖;
将 Symbol 值用于属性定义或属性调用时, Symbol 值必须放在方括号中; (Symbol 值本身被存储在变量中, 因此要符合变量调用的方式)
1 |
|
Symbol 值作为属性名时, 属性是公开的而不是私有的:
- Symbol 属性名不会被 for…in, for…of 遍历, 也不会被 Object.keys(), Object.getOwnPropertyNames(), JSON.stringify() 查找;
- Symbol 属性名只能被 Obeject.getOwnPropertySymbols() 和 Reflect.ownKeys() 查找, 因此它不是私有属性;
基于 Symbol 值的特性(不会被常规方法遍历访问), 我们可以用 Symbol 为对象定义一些非私有的, 但只用于内部的属性;
1 |
|
Symbol.for()
Symbol.for()
接收一个字符串作为参数, 它会在全局环境中搜索是否存在该参数名的 Symbol 值, 若存在, 则返回该 Symbol 值, 若不存在, 则新建一个以该字符串为名称的 Symbol 值, 并注册到全局;
1 |
|
注: 通过 Symbol() 创建的 Symbol 值不会被登记在全局环境中, 因此不能被 Symbol.for() 搜索, 所以 foo === foo1
结果为 false; 通过 Symbol.for() 创建的 Symbol 值会被登记在全局环境中, foo1
通过 Symbol.for('foo')
创建后, 全局环境中被登记了一个名为 foo 的 Symbol 值, 因此 foo2
接收的就是该 Symbol 值, 所以两者相等;
Symbol.for() 与 Symbol()
共同点: 都用于生成 Symbol 值;
区别: 前者会被登记在全局环境中供搜索, 后者不会;
Symbol.for()不会每次调用就返回一个新的 Symbol 类型的值, 而是会先检查给定的key是否已经存在, 如果不存在才会新建一个值;
由于Symbol()写法没有登记机制, 所以每次调用都会返回一个不同的值
Symbol.keyFor()
返回一个已登记的 Symbol 类型值的 key;
1 |
|
内置的 Symbol 值
- Symbol.hasInstance
- Symbol.isConcatSpreadable
- Symbol.species
- Symbol.match
- Symbol.replace
- Symbol.search
- Symbol.split
- Symbol.iterator
- Symbol.toPrimitive
- Symbol.toStringTag
- Symbol.unscopables
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!