符号

符号是相对较新的 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 创建符号?

以下哪一项描述的是“已知”符号?

用于访问和修改 JavaScript 代码的唯一属性键 内置方法
`Symbol` 对象的静态属性
您经常使用的符号