aboutsummaryrefslogtreecommitdiff
path: root/files/ja/web/javascript/reference/global_objects/symbol/index.html
blob: 54ccbf84aad0bc3f1ef3515a896b2623267b1746 (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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
---
title: Symbol
slug: Web/JavaScript/Reference/Global_Objects/Symbol
tags:
  - Class
  - ECMAScript 2015
  - JavaScript
  - Symbol
translation_of: Web/JavaScript/Reference/Global_Objects/Symbol
---
<div>{{JSRef}}</div>

<p>データ型 <strong>symbol</strong> は、<a href="/ja/docs/Glossary/Primitive">プリミティブデータ型</a>です。<code>Symbol()</code> 関数は、<strong>symbol</strong> 型の値を返します。これは組み込みオブジェクトを公開するための静的プロパティを持ち、グローバルシンボルレジストリを公開するための静的メソッドを持つので、組み込みオブジェクトクラスのようにも見えますが、コンストラクターとしての機能を持たず、"<code>new Symbol()</code>" はサポートされていません。</p>

<p><code>Symbol()</code> から返されるすべてのシンボル値は一意です。シンボル値は、オブジェクトプロパティの識別子として使用できます。これがデータ型の主な利用目的ですが、不透明なデータ型の有効化や、実装サポートされている一意の識別子として機能するなど、他の利用目的も存在します。目的や使用方法に関する詳細を知りたい場合、<a href="/ja/docs/Glossary/Symbol">MDN用語集:Symbol</a> を見てください。</p>

<h2 id="Description" name="Description">説明</h2>

<p>新しいプリミティブシンボルを生成するために、説明のためのオプション文字列とともに <code>Symbol()</code> を記述します。</p>

<pre class="brush: js notranslate">let sym1 = Symbol()
let sym2 = Symbol('foo')
let sym3 = Symbol('foo')
</pre>

<p>上のコードでは、3 つの新しいシンボルを作成しています。<code>Symbol('foo')</code> は文字列 <code>'foo'</code> を強制的にシンボルにしているわけではなく、毎回新しいシンボルを生成していることに注意してください。</p>

<pre class="brush: js notranslate">Symbol('foo') === Symbol('foo')  // false
</pre>

<p>次の {{jsxref("Operators/new", "new")}} 演算子を用いた構文では、{{jsxref("TypeError")}} が投げられます。</p>

<pre class="brush: js notranslate">let sym = new Symbol()  // TypeError
</pre>

<p>これにより、新しいシンボル値を生成する代わりに明示的な <code>Symbol</code> ラッパーオブジェクトを生成することを防ぎます。プリミティブデータ型の周りに明示的なラッパーオブジェクトを生成することは、もはや ECMAScript6 ではサポートされていません。しかし、<code>new Boolean</code><code>new String</code><code>new Number</code> のような既存のプリミティブラッパーオブジェクトは、歴史的な理由からまだ生成できます。</p>

<p>もし本当に <code>Symbol</code> ラッパーオブジェクトを生成したいのなら、<code>Object()</code> 関数を使用できます。</p>

<pre class="brush: js notranslate">let sym = Symbol('foo')
typeof sym      // "symbol"
let symObj = Object(sym)
typeof symObj   // "object"
</pre>

<h3 id="Shared_symbols_in_the_global_symbol_registry" name="Shared_symbols_in_the_global_symbol_registry">グローバルシンボルレジストリの共有シンボル</h3>

<p>上述の <code>Symbol()</code> 関数を使用した構文は、コードベース全体で使用できるグローバルシンボルは作成されません。ファイルを跨いでグローバルスコープのような環境でも利用可能なシンボルを作成するには、{{jsxref("Symbol.for()")}}{{jsxref("Symbol.keyFor()")}} のメソッドを使用して、グローバルシンボルレジストリからシンボルを設定および取得します。</p>

<h3 id="Finding_symbol_properties_on_objects" name="Finding_symbol_properties_on_objects">オブジェクトのシンボルプロパティを探す</h3>

<p>{{jsxref("Object.getOwnPropertySymbols()")}} メソッドは、シンボルの配列を返し、与えられたオブジェクトのシンボルプロパティを見つけることができます。すべてのオブジェクトは、シンボルなしで初期化されます。そのため、オブジェクトにシンボルプロパティを設定しないかぎり、この配列は空だということに注意してください。</p>

<h2 id="Constructor" name="Constructor">コンストラクター</h2>

<dl>
 <dt><a href="/ja/docs/Web/JavaScript/Reference/Global_Objects/Symbol/Symbol"><code>Symbol()</code></a></dt>
 <dd>新しい <code>Symbol</code> オブジェクトを作成します。"<code>new Symbol()</code>" という構文をサポートしていないので、コンストラクターとしては不完全です。</dd>
</dl>

<h2 id="Static_properties" name="Static_properties">静的プロパティ</h2>

<dl>
 <dt>{{jsxref("Symbol.asyncIterator")}}</dt>
 <dd>オブジェクトのデフォルトの AsyncIterator を返すメソッド。<a href="/ja/docs/Web/JavaScript/Reference/Statements/for-await...of"><code>for await...of</code></a> によって使用されます。</dd>
 <dt>{{jsxref("Symbol.hasInstance")}}</dt>
 <dd>コンストラクターのオブジェクトがオブジェクトをインスタンスとして認識しているかどうかを判定するメソッド。{{jsxref("Operators/instanceof", "instanceof")}} によって使用されます。</dd>
 <dt>{{jsxref("Symbol.isConcatSpreadable")}}</dt>
 <dd>オブジェクトをその配列要素にフラット化する必要があるかどうかを示すブール値。{{jsxref("Array.prototype.concat()")}} によって使用されます。</dd>
 <dt>{{jsxref("Symbol.iterator")}}</dt>
 <dd>オブジェクトのデフォルトのイテレーターを返すメソッド。<a href="/ja/docs/Web/JavaScript/Reference/Statements/for...of"><code>for...of</code></a> によって使用されます。</dd>
 <dt>{{jsxref("Symbol.match")}}</dt>
 <dd>文字列と照合するメソッド。オブジェクトを正規表現として使用できるかどうかを判断するためにも使用されます。{{jsxref("String.prototype.match()")}} によって使用されます。</dd>
 <dt>{{jsxref("Symbol.matchAll")}}</dt>
 <dd>文字列に対する正規表現の一致を生成するイテレーターを返すメソッド。{{jsxref("String.prototype.matchAll()")}} によって使用されます。</dd>
 <dt>{{jsxref("Symbol.replace")}}</dt>
 <dd>文字列の一致した部分文字列を置き換えるメソッド。{{jsxref("String.prototype.replace()")}} によって使用されます。</dd>
 <dt>{{jsxref("Symbol.search")}}</dt>
 <dd>正規表現に一致する文字列内のインデックスを返すメソッド。{{jsxref("String.prototype.search()")}} によって使用されます。</dd>
 <dt>{{jsxref("Symbol.split")}}</dt>
 <dd>正規表現に一致するインデックスで文字列を分割するメソッド。{{jsxref("String.prototype.split()")}} によって使用されます。</dd>
 <dt>{{jsxref("Symbol.species")}}</dt>
 <dd>派生オブジェクトを作成するためのコンストラクタ関数。</dd>
 <dt>{{jsxref("Symbol.toPrimitive")}}</dt>
 <dd>オブジェクトをプリミティブ値に変換するメソッド。</dd>
 <dt>{{jsxref("Symbol.toStringTag")}}</dt>
 <dd>オブジェクトのデフォルトの説明に使用される文字列の値。{{jsxref("Object.prototype.toString()")}} によって使用されます。</dd>
 <dt>{{jsxref("Symbol.unscopables")}}</dt>
 <dd>自身のプロパティ名と継承されたプロパティ名が、関連付けられたオブジェクトの <code><a href="/ja/docs/Web/JavaScript/Reference/Statements/with">with</a></code> 環境バインディングから除外されているオブジェクトの値。</dd>
</dl>

<h2 id="Static_methods" name="Static_methods">静的メソッド</h2>

<dl>
 <dt>{{jsxref("Symbol.for()", "Symbol.for(key)")}}</dt>
 <dd>指定された <code><var>key</var></code> を使用して既存のシンボルを検索し、見つかればそれを返します。そうでない場合は、この <code><var>key</var></code> で グローバルシンボルレジストリに新しいシンボルが作成されます。</dd>
 <dt>{{jsxref("Symbol.keyFor", "Symbol.keyFor(sym)")}}</dt>
 <dd>指定したシンボルのグローバルシンボルレジストリから共有シンボルキーを取得します。</dd>
</dl>

<h2 id="Instance_properties" name="Instance_properties">インスタンスプロパティ</h2>

<dl>
 <dt>{{jsxref("Symbol.prototype.description")}}</dt>
 <dd>シンボルの説明を含む読み取り専用の文字列。</dd>
</dl>

<h2 id="Instance_methods" name="Instance_methods">インスタンスメソッド</h2>

<dl>
 <dt>{{jsxref("Symbol.prototype.toSource()")}}</dt>
 <dd>{{jsxref("Global_Objects/Symbol", "Symbol")}} オブジェクトのソースを含む文字列を返します。{{jsxref("Object.prototype.toSource()")}} メソッドを上書きします。</dd>
 <dt>{{jsxref("Symbol.prototype.toString()")}}</dt>
 <dd>シンボルの説明を含む文字列を返します。{{jsxref("Object.prototype.toString()")}} メソッドを上書きします。</dd>
 <dt>{{jsxref("Symbol.prototype.valueOf()")}}</dt>
 <dd>{{jsxref("Symbol")}} オブジェクトのプリミティブ値を返します。{{jsxref("Object.prototype.valueOf()")}} メソッドを上書きします。</dd>
 <dt>{{jsxref("Symbol.prototype.@@toPrimitive()", "Symbol.prototype[@@toPrimitive]")}}</dt>
 <dd>{{jsxref("Symbol")}} オブジェクトのプリミティブ値を返します。</dd>
</dl>

<h2 id="Examples" name="Examples"></h2>

<h3 id="Using_the_typeof_operator_with_symbols" name="Using_the_typeof_operator_with_symbols">シンボルと一緒に <code>typeof</code> 演算子を使用する</h3>

<p>{{jsxref("Operators/typeof", "typeof")}} 演算子は、シンボルを識別するために役立ちます。</p>

<pre class="brush: js notranslate">typeof Symbol() === 'symbol'
typeof Symbol('foo') === 'symbol'
typeof Symbol.iterator === 'symbol'
</pre>

<h3 id="Symbol_type_conversions" name="Symbol_type_conversions">シンボルの型変換</h3>

<p>シンボルの型変換作業を行うとき、いくつかの点に注意してください。</p>

<ul>
 <li>シンボルを数値に変換しようとすると、{{jsxref("TypeError")}} が投げられます(例: <code>+<var>sym</var></code> または <code><var>sym</var> | 0</code> )。</li>
 <li>緩い等価演算子を使うとき、<code>Object(<var>sym</var>) == <var>sym</var></code><code>true</code> を返します。</li>
 <li><code>Symbol('foo') + 'bar'</code>{{jsxref("TypeError")}}(シンボルを文字列に変換できません)を投げます。これは新しい文字列プロパティ名を暗黙的に生成することを防ぎます。</li>
 <li><a href="/ja/docs/Web/JavaScript/Reference/Global_Objects/String#String_conversion">"安全な" <code>String(<var>sym</var>)</code> 変換</a>はシンボルとともに {{jsxref("Symbol.prototype.toString()")}} を呼び出したかのように動作しますが、<code>new String(<var>sym</var>)</code> は TypeError を投げることに注意してください。</li>
</ul>

<h3 id="Symbols_and_for...in_iteration" name="Symbols_and_for...in_iteration">シンボルと <code>for...in</code> による反復</h3>

<p>シンボルは <code><a href="/ja/docs/Web/JavaScript/Reference/Statements/for...in">for...in</a></code> よる反復からは取得できません。加えて、{{jsxref("Object.getOwnPropertyNames()")}} はシンボルオブジェクトプロパティを返しません、それらを取得するために {{jsxref("Object.getOwnPropertySymbols()")}} を使うことができます。</p>

<pre class="brush: js notranslate">let obj = {}

obj[Symbol('a')] = 'a'
obj[Symbol.for('b')] = 'b'
obj['c'] = 'c'
obj.d = 'd'

for (let i in obj) {
   console.log(i)  // logs "c" and "d"
}</pre>

<h3 id="Symbols_and_JSON.stringify" name="Symbols_and_JSON.stringify()">シンボルと <code>JSON.stringify()</code></h3>

<p><code>JSON.stringify()</code> を使用するとき、シンボルをキーとしたプロパティは完全に無視されます。</p>

<pre class="brush: js notranslate">JSON.stringify({[Symbol('foo')]: 'foo'})
// '{}'
</pre>

<p>詳しくは {{jsxref("JSON.stringify()")}} を見てください。</p>

<h3 id="Symbol_wrapper_objects_as_property_keys" name="Symbol_wrapper_objects_as_property_keys">プロパティキーとしてのシンボルラッパーオブジェクト</h3>

<p>シンボルラッパーオブジェクトがプロパティキーとして使用されている場合、このオブジェクトはそのラップされたシンボルを強制的に使用します。</p>

<pre class="brush: js notranslate">let sym = Symbol('foo')
let obj = {[sym]: 1}
obj[sym]             // 1
obj[Object(sym)]     // still 1
</pre>

<h2 id="Specifications" name="Specifications">仕様</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">仕様書</th>
  </tr>
  <tr>
   <td>{{SpecName('ESDraft', '#sec-symbol-objects', 'Symbol')}}</td>
  </tr>
 </tbody>
</table>

<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザー実装状況</h2>



<p>{{Compat("javascript.builtins.Symbol")}}</p>

<h2 id="See_also" name="See_also">関連項目</h2>

<ul>
 <li><a href="/ja/docs/Glossary/Symbol">用語集: Symbol</a></li>
 <li>{{jsxref("Operators/typeof", "typeof")}}</li>
 <li><a href="/ja/docs/Web/JavaScript/Data_structures">データ型とデータ構造</a></li>
 <li><a href="https://hacks.mozilla.org/2015/06/es6-in-depth-symbols/">"ES6 In Depth: Symbols" on hacks.mozilla.org</a></li>
</ul>