7.7 Symbol 包装对象

虽然其它所有原始类型都有字面量形式的值,但是要创建 Symbol 对象,还是得调用Symbol函数。因此,有时候很容易把 Symbol 函数当成构造函数使用。虽然这会返回 Symbol 的一个实例,但是并没有什么用。所以,如果把 Symbol 函数当成构造函数使用的话,会抛出异常:

> new Symbol()
TypeError: Symbol is not a constructor

有一种创建包装对象的方法:将 Object 当做一个普通函数调用,会将所有的值(包括 Symbol )转换成对象。

> const sym = Symbol();
> typeof sym
'symbol'

> const wrapper = Object(sym);
> typeof wrapper
'object'
> wrapper instanceof Symbol
true

7.7.1 使用 [] 和包装对象键访问属性

用来访问属性的方括号操作符 [] 会将字符串包装对象和 Symbol 包装对象解包装。我们可以使用如下的对象来检测这个现象。

const sym = Symbol('yes');
const obj = {
    [sym]: 'a',
    str: 'b',
};

使用交互模式:

> const wrappedSymbol = Object(sym);
> typeof wrappedSymbol
'object'
> obj[wrappedSymbol]
'a'

> const wrappedString = new String('str');
> typeof wrappedString
'object'
> obj[wrappedString]
'b'

7.7.1.1 规范中关于属性访问的说明

获取和设置属性的操作是通过内部的 ToPropertyKey() 操作实现的,其工作过程如下:

  • ToPrimitive() 把操作数转换成原始值类型(优先选用 string 类型):
    • 如果是原始值,就返回自身。
    • 对于非 Symbol 对象,如果 toString() 返回原始值,就使用 toString() 转换;否则,如果 valueOf() 返回原始值,就使用 valueOf() ;否则,抛出 TypeError 错误。
    • Symbol 对象是一个例外:它们会被转换成原始的 Symbol (解包装)。
  • 如果转换结果是 Symbol 原始值,直接返回该值。
  • 否则,通过 ToString() 强制将结果转换成字符串。

results matching ""

    No results matching ""