# 十三、符号 符号是 ES6 中一种新的基本类型。`Symbols`是用作唯一标识的令牌。您可以通过工厂功能`Symbol()`创建符号。 让我们看一个使用符号的例子: 代码清单 191 ```js 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 ```js {} [] [] [ Symbol(test1), Symbol(test2) ] ``` 鉴于我们现在有一种新的值可以成为属性的关键,以下术语用于 ES6: * 属性键–可以是字符串或符号 * 属性名–是字符串 `Object.keys()`这个名字其实并不起作用。它只考虑字符串属性键。这解释了为什么我们的输出只有一个空数组(`[]`)。 同样,名称`Object.getOwnPropertyName()`也只返回字符串形式的属性键。 如果您希望一个符号在所有领域都是相同的,您需要通过全局符号注册表来创建它。让我们看看下面的例子: 代码清单 193 ```js 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 ```js {} [] [] [ Symbol(app.foo), Symbol(app.bar) ] ```