符号是 ES6 中一种新的基本类型。Symbols
是用作唯一标识的令牌。您可以通过工厂功能Symbol()
创建符号。
让我们看一个使用符号的例子:
代码清单 191
Symbol("foo") !==
Symbol("foo")
const foo = Symbol('test1');
const bar = Symbol('test2');
typeof foo === "symbol";
typeof bar === "symbol";
let obj = {};
obj[foo]
= "foo";
obj[bar]
= "bar";
console.log(JSON.stringify(obj));
console.log(Object.keys(obj));
console.log(Object.getOwnPropertyNames(obj));
console.log(Object.getOwnPropertySymbols(obj));
如你所见,符号是唯一的,没有两个符号会彼此相等。还要注意我们如何将符号分配给对象属性。我们使用符号作为对象的键,并为其赋值。还要注意,您可以将字符串传递给符号的构造函数,但它仅用于调试目的。
让我们看看前面代码的输出:
代码清单 192
{}
[]
[]
[ Symbol(test1), Symbol(test2) ]
鉴于我们现在有一种新的值可以成为属性的关键,以下术语用于 ES6:
- 属性键–可以是字符串或符号
- 属性名–是字符串
Object.keys()
这个名字其实并不起作用。它只考虑字符串属性键。这解释了为什么我们的输出只有一个空数组([]
)。
同样,名称Object.getOwnPropertyName()
也只返回字符串形式的属性键。
如果您希望一个符号在所有领域都是相同的,您需要通过全局符号注册表来创建它。让我们看看下面的例子:
代码清单 193
Symbol.for("app.foo")
=== Symbol.for("app.foo")
const foo = Symbol.for("app.foo")
const bar = Symbol.for("app.bar")
Symbol.keyFor(foo)
=== "app.foo"
Symbol.keyFor(bar)
=== "app.bar"
typeof foo === "symbol"
typeof bar === "symbol"
let obj = {}
obj[foo]
= "foo"
obj[bar]
= "bar"
console.log(JSON.stringify(obj));
console.log(Object.keys(obj));
console.log(Object.getOwnPropertyNames(obj));
console.log(Object.getOwnPropertySymbols(obj));
请注意,我们现在有Symbol.for
功能。这就是我们在全球注册中心放置符号的方式。还要注意我们如何使用Symbol.keyFor
功能为符号分配一个键。
从前面代码的输出中我们可以看到,全局符号的行为与普通符号相同:
代码清单 194
{}
[]
[]
[ Symbol(app.foo), Symbol(app.bar) ]