符号是相对较新的 ES6 中引入的基元。符号基元表示 绝不会与任何其他值(包括其他符号基元的值)冲突。 由相同字符组成的两个字符串基元严格按照 等于:
String() === String()
> true
String( "My string." ) === String( "My string." );
> true
不过,使用 Symbol()
函数创建的两个符号永远不能
严格相等:
Symbol() === Symbol()
> false
此 trait 允许您将符号用作对象中的唯一属性键,从而防止 与任何其他代码可能添加到该对象中的键冲突的情况。
const mySymbol = Symbol( "Desc" );
const myObject = {
}
myObject
> Object { Symbol("Desc"): "propSymbol" }
有三种类型的符号:
- 使用
Symbol()
创建的符号 - 使用
Symbol.for()
- “知名符号”在 Symbol 对象上定义为静态属性。 这些符号包含无法意外覆盖的内部方法。
Symbol()
接受说明(或“符号名称”)作为可选参数。
这些描述是用于调试目的的人类可读标签,
不会影响结果的唯一性。对 Symbol
的任何调用都会返回一个
完全唯一的符号基元,即使多个调用具有相同的
说明:
Symbol( "My symbol." ) === Symbol( "My symbol." );
> false
与其他原始数据类型一样,符号从 原型。例如,您可以访问说明,将其作为已创建符号的继承属性:
let mySymbol = Symbol( "My symbol." );
mySymbol.description
> "My symbol."
但是,您无法使用 new
关键字创建符号:
let mySymbol = new Symbol();
> Uncaught TypeError: Symbol is not a constructor
符号不可枚举,这意味着符号属性不可用
需要注意的一点是getOwnPropertySymbols()
方法可以访问对象的符号属性。
共享符号
Symbol.for()
方法会尝试在
使用给定字符串作为键的运行时级全局符号注册表,并返回
如果找到匹配符号,则会将其返回。如果未找到,则会创建一个符号
并将它添加到全局注册表:
let sharedSymbol = Symbol.for( "My key." );
sharedSymbol === Symbol.for( "My key." )
> true
这些键与分配给
作者创建的 Symbol
基元。如需访问符号注册表中的符号,请按以下步骤操作:
必须先使用 for()
创建它:
Symbol( "String" ) === Symbol( "String" );
> false
Symbol( "String" ) === Symbol().for( "String" );
> false
Symbol().for( "String" ) === Symbol().for( "String" );
> true
要从符号注册表中检索任何符号的键,请使用
Symbol.keyFor()
:
let mySymbol = Symbol.for( "Key." );
Symbol.keyFor( mySymbol ) ;
> "Key."
“众所周知”符号
众所周知的符号是 Symbol
对象的静态属性,其中每个属性
它本身就是一种符号知名符号为
访问和修改 JavaScript 的内置方法,同时阻止核心
避免行为被无意中覆盖
Symbol;
> function Symbol()
asyncIterator: Symbol(Symbol.asyncIterator)
for: function for()
hasInstance: Symbol("Symbol.hasInstance")
isConcatSpreadable: Symbol("Symbol.isConcatSpreadable")
iterator: Symbol(Symbol.iterator)
keyFor: function keyFor()
length: 0
match: Symbol("Symbol.match")
matchAll: Symbol("Symbol.matchAll")
name: "Symbol"
prototype: Object { … }
replace: Symbol("Symbol.replace")
search: Symbol("Symbol.search")
species: Symbol("Symbol.species")
split: Symbol("Symbol.split")
toPrimitive: Symbol("Symbol.toPrimitive")
toStringTag: Symbol("Symbol.toStringTag")
unscopables: Symbol("Symbol.unscopables")
<prototype>: function ()
由于符号是 ES6 特有的功能,因此这些符号值 旨在用作“延伸点”适用于修改 JavaScript 的开发者 行为,而不会引入向后兼容性问题。
知名的符号值通常采用
@@
前缀或封装在 %
中
区分其密钥与可变原型。例如:@@match
(或 %match%
)是对不可变 Symbol.match
的引用,而不是
String.prototype.match
。
检查您的理解情况
您能否使用 new
创建符号?
以下哪一项描述的是“已知”符号?