aboutsummaryrefslogtreecommitdiff
path: root/files/zh-cn/glossary/symbol/index.html
blob: aa1615159e45aed59c8787da850738d9038a4ba1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
---
title: Symbol
slug: Glossary/Symbol
tags:
  - JavaScript
  - Symbol
translation_of: Glossary/Symbol
---
<p>这个技术术语页面同时描述了一种称为 “<strong>symbol</strong>” 的数据类型,可以通过调用函数 “{{jsxref("Symbol")}}<code>()</code>”,用来创建 <strong>symbol</strong> 数据类型实例。</p>

<p>数据类型 “<strong>symbol</strong>” 是一种基本数据类型,该类型的性质在于这个类型的值可以用来创建匿名的对象属性。该数据类型通常被用作一个对象属性的键值——当你想让它是私有的时候。例如,<strong>symbol </strong>类型的键存在于各种内置的 JavaScript 对象中。同样,自定义类也可以这样创建私有成员。<strong>symbol </strong>数据类型具有非常明确的目的,并且因为其功能性单一的优点而突出;一个 <strong>symbol </strong>实例可以被赋值到一个左值变量,还可以通过标识符检查类型,这就是它的全部特性。不能对该类型实例使用其他操作符(将“<strong>Symbol</strong>”类型的实例与 “<strong>Number</strong>” 类型的实例对比,例如整数 42,该实例就具有将值与其他类型的值进行比较或组合的运算符)。</p>

<p>一个具有数据类型 “<strong>symbol</strong>” 的值可以被称为 “符号类型值”。在 JavaScript 运行时环境中,一个符号类型值可以通过调用函数 <code>Symbol()</code> 创建,这个函数动态地生成了一个匿名,唯一的值。Symbol类型唯一合理的用法是用变量存储 symbol的值,然后使用存储的值创建对象属性。以下示例使用"<code>var</code>"创建一个变量来保存 symbol。</p>

<pre class="brush: js notranslate">var  myPrivateMethod  = Symbol();
this[myPrivateMethod] = function() {...};</pre>

<p>当一个 symbol 类型的值在属性赋值语句中被用作标识符,该属性(像这个 symbol 一样)是匿名的;并且是不可枚举的。因为这个属性是不可枚举的,它不会在循环结构 “<code>for( ... in ...)</code>” 中作为成员出现,也因为这个属性是匿名的,它同样不会出现在 “<code>Object.getOwnPropertyNames()</code>” 的返回数组里。这个属性可以通过创建时的原始 symbol 值访问到,或者通过遍历 “<code>Object.getOwnPropertySymbols()</code>” 返回的数组。在之前的代码示例中,通过保存在变量 <code>myPrivateMethod</code>的值可以访问到对象属性。</p>

<p>内置函数 “{{jsxref("Symbol")}}<code>()</code>” 是一个不完整的类,当作为函数调用时会返回一个 symbol 值,试图通过语法 “<code>new Symbol()</code>” 作为构造函数调用时会抛出一个错误。它有一些静态方法来访问 JavaScript 全局 symbol 表,还有一些静态属性用来保存已存在通用对象里的特定 symbol 地址。通过 <code>Symbol()</code> 函数创建 symbol 值已在上面解释过。理解试图将 <code>Symbol()</code>作为构造函数使用会抛出错误可以提前预防意外(当作构造函数使用)创建对象导致的混乱。访问全局 symbol 注册表的方法是 <code>Symbol.for()</code><code>Symbol.keyFor()</code>;它们斡旋在全局 symbol 表(或注册表)与运行时环境之间。symbol 注册表通常构建在 JavaScript 编译器基础设施,所以 symbol 注册表的内容不会出现 JavaScript 运行时环境,除了通过它们的反射方法。<em><code>Symbol.for("tokenString")</code></em> 方法从注册表返回一个 symbol 值,<em><code>Symbol.keyFor(symbolValue)</code></em> 方法从注册表返回 token 字符串;正好相反,所以下面为 true:</p>

<pre class="brush: js notranslate">Symbol.keyFor(Symbol.for("tokenString"))=="tokenString";  // true
</pre>

<p><strong>Symbol </strong>类具有一些静态属性,对于匿名命名来说,这带有一点讽刺意味。这类属性只有几个; 它们是所谓的“众所周知”的 symbol。 它们是在某些内置对象中找到的某些特定方法属性的 symbol。 暴露出这些 symbol 使得可以直接访问这些行为;这样的访问可能是有用的,例如在定义自定义类的时候。 普遍的 symbol 的例子有:“<code>Symbol.iterator</code>”用于类似数组的对象,“<code>Symbol.search</code>”用于字符串对象。</p>

<p><code>Symbol()</code>函数及其创建的 symbol 值可能对设计自定义类的编程人员有用。 symbol 值提供了一种自定义类可以创建私有成员的方式,并维护一个仅适用于该类的 symbol 注册表。 自定义类可以使用 symbol 值来创建“自有”属性,这些属性避免了不必要的被偶然发现带来的影响。 在类定义中,动态创建的 symbol 值将保存到作用域变量中,该变量只能在类定义中私有地使用。 没有 token 字符串; 作用域变量起到 token 的等同作用。</p>

<p>Symbol 是 {{Glossary("JavaScript")}}{{Glossary("Primitive", "原始数据类型")}} ,Symbol实例是唯一且不可改变的.  </p>

<p>在一些编程语言中 symbol也被称为原子(atoms).</p>

<p>{{Glossary("JavaScript")}}中,Symbol 是 {{Glossary("Primitive", "基本数据类型")}} 的一种,{{jsxref("Symbol")}} 对象是 Symbol原始值的{{Glossary("Wrapper", "封装")}}</p>

<p>Symbol 的描述是可选的,但仅用于调试目的。</p>

<p>Symbol 类型是 ECMAScript 2015 中新添加的特性,在ECMAScript 5中没有对应的类型。</p>

<pre class="brush: js notranslate">Symbol("foo") !== Symbol("foo")
const foo = Symbol()
const bar = Symbol()
typeof foo === "symbol"
typeof bar === "symbol"
let obj = {}
obj[foo] = "foo"
obj[bar] = "bar"
JSON.stringify(obj) // {}
Object.keys(obj) // []
Object.getOwnPropertyNames(obj) // []
Object.getOwnPropertySymbols(obj) // [ foo, bar ]</pre>

<h2 id="了解更多">了解更多</h2>

<h3 id="常识">常识</h3>

<ul>
 <li>{{Interwiki("wikipedia", "Symbol (programming)")}} on Wikipedia</li>
 <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures">JavaScript data types and data structures</a></li>
 <li><a href="http://2ality.com/2014/12/es6-symbols.html">Symbols in ECMAScript 6</a></li>
</ul>