7.2 新的原始类型

ECMAScript 6 引入了一种新的原始类型: symbol 。它能被用作唯一标识的 ID 。通过工厂方法 Symbol() 来创建 symbol 对象(这跟 String 方法返回字符串很类似):

const symbol1 = Symbol();

Symbol() 有一个可选的字符串参数,用作新创建的 symbol 对象的一个描述文本。该文本在 symbol 被转换为字符串(通过 toString() 或者 String() )的时候用到:

> const symbol2 = Symbol('symbol2');
> String(symbol2)
'Symbol(symbol2)'

Symbol() 方法返回的每一个 symbol 实例都是唯一的,每一个 symbol 对象都有自己的标识:

> Symbol() === Symbol()
false

如果你用 typeof 来检测 symbol 对象,会发现 symbol 是原始类型,因为返回值是一种新的特定于 symbol 对象的类型:

> typeof Symbol()
'symbol'

7.2.1 用作属性键的 symbol

symbol 可以用作属性键:

const MY_KEY = Symbol();
const obj = {};

obj[MY_KEY] = 123;
console.log(obj[MY_KEY]); // 123

类和对象字面量有一个叫做计算属性键的特性:你可以用一个表达式来指定属性键,将表达式放置在中括号里面。如下的对象字面量,使用了计算属性键的方式,让 MY_KEY 成为了键。

const MY_KEY = Symbol();
const obj = {
    [MY_KEY]: 123
};

计算键同样适用于方法定义:

const FOO = Symbol();
const obj = {
    [FOO]() {
        return 'bar';
    }
};
console.log(obj[FOO]()); // bar

7.2.2 枚举自有属性键

鉴于现在有一种新的可以用作属性键的值了,那么 ECMAScript 6 中就产生了新的术语:

  • 属性键要么是字符串,要么是 symbol 对象。
  • 字符串形式的属性键叫做属性名字
  • symbol 对象形式的属性键叫做属性 symbol

我们先创建一个对象,然后用这个对象来验证新的自有属性枚举 API 。

const obj = {
    [Symbol('my_key')]: 1,
    enum: 2,
    nonEnum: 3
};
Object.defineProperty(obj,
    'nonEnum', { enumerable: false });

Object.getOwnPropertyNames() 忽略 symbol 形式的属性键:

> Object.getOwnPropertyNames(obj)
['enum', 'nonEnum']

Object.getOwnPropertySymbols() 忽略字符串形式的属性键:

> Object.getOwnPropertySymbols(obj)
[Symbol(my_key)]

Reflect.ownKeys() 返回所有类型的键:

> Reflect.ownKeys(obj)
[Symbol(my_key), 'enum', 'nonEnum']

Object.keys() 仅返回可枚举的字符串属性:

> Object.keys(obj)
['enum']

Object.keys 这个名字与新术语(仅列举字符串类型的键)冲突了。现在, Object.names 或者 Object.getEnumerableOwnPropertyNames 会是更好的选择。

results matching ""

    No results matching ""