# 十三、符号

符号是 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) ]

```