--- title: Symbol slug: Web/JavaScript/Reference/Global_Objects/Symbol tags: - Class - ECMAScript 2015 - JavaScript - Symbol translation_of: Web/JavaScript/Reference/Global_Objects/Symbol ---
データ型 symbol は、プリミティブデータ型です。Symbol()
関数は、symbol 型の値を返します。これは組み込みオブジェクトを公開するための静的プロパティを持ち、グローバルシンボルレジストリを公開するための静的メソッドを持つので、組み込みオブジェクトクラスのようにも見えますが、コンストラクターとしての機能を持たず、"new Symbol()
" はサポートされていません。
Symbol()
から返されるすべてのシンボル値は一意です。シンボル値は、オブジェクトプロパティの識別子として使用できます。これがデータ型の主な利用目的ですが、不透明なデータ型の有効化や、実装サポートされている一意の識別子として機能するなど、他の利用目的も存在します。目的や使用方法に関する詳細を知りたい場合、MDN用語集:Symbol を見てください。
新しいプリミティブシンボルを生成するために、説明のためのオプション文字列とともに Symbol()
を記述します。
let sym1 = Symbol() let sym2 = Symbol('foo') let sym3 = Symbol('foo')
上のコードでは、3 つの新しいシンボルを作成しています。Symbol('foo')
は文字列 'foo'
を強制的にシンボルにしているわけではなく、毎回新しいシンボルを生成していることに注意してください。
Symbol('foo') === Symbol('foo') // false
次の {{jsxref("Operators/new", "new")}} 演算子を用いた構文では、{{jsxref("TypeError")}} が投げられます。
let sym = new Symbol() // TypeError
これにより、新しいシンボル値を生成する代わりに明示的な Symbol
ラッパーオブジェクトを生成することを防ぎます。プリミティブデータ型の周りに明示的なラッパーオブジェクトを生成することは、もはや ECMAScript6 ではサポートされていません。しかし、new Boolean
や new String
、new Number
のような既存のプリミティブラッパーオブジェクトは、歴史的な理由からまだ生成できます。
もし本当に Symbol
ラッパーオブジェクトを生成したいのなら、Object()
関数を使用できます。
let sym = Symbol('foo') typeof sym // "symbol" let symObj = Object(sym) typeof symObj // "object"
上述の Symbol()
関数を使用した構文は、コードベース全体で使用できるグローバルシンボルは作成されません。ファイルを跨いでグローバルスコープのような環境でも利用可能なシンボルを作成するには、{{jsxref("Symbol.for()")}} と {{jsxref("Symbol.keyFor()")}} のメソッドを使用して、グローバルシンボルレジストリからシンボルを設定および取得します。
{{jsxref("Object.getOwnPropertySymbols()")}} メソッドは、シンボルの配列を返し、与えられたオブジェクトのシンボルプロパティを見つけることができます。すべてのオブジェクトは、シンボルなしで初期化されます。そのため、オブジェクトにシンボルプロパティを設定しないかぎり、この配列は空だということに注意してください。
Symbol()
Symbol
オブジェクトを作成します。"new Symbol()
" という構文をサポートしていないので、コンストラクターとしては不完全です。for await...of
によって使用されます。for...of
によって使用されます。with
環境バインディングから除外されているオブジェクトの値。key
を使用して既存のシンボルを検索し、見つかればそれを返します。そうでない場合は、この key
で グローバルシンボルレジストリに新しいシンボルが作成されます。typeof
演算子を使用する{{jsxref("Operators/typeof", "typeof")}} 演算子は、シンボルを識別するために役立ちます。
typeof Symbol() === 'symbol' typeof Symbol('foo') === 'symbol' typeof Symbol.iterator === 'symbol'
シンボルの型変換作業を行うとき、いくつかの点に注意してください。
+sym
または sym | 0
)。Object(sym) == sym
は true
を返します。Symbol('foo') + 'bar'
は {{jsxref("TypeError")}}(シンボルを文字列に変換できません)を投げます。これは新しい文字列プロパティ名を暗黙的に生成することを防ぎます。String(sym)
変換はシンボルとともに {{jsxref("Symbol.prototype.toString()")}} を呼び出したかのように動作しますが、new String(sym)
は TypeError を投げることに注意してください。for...in
による反復シンボルは for...in
よる反復からは取得できません。加えて、{{jsxref("Object.getOwnPropertyNames()")}} はシンボルオブジェクトプロパティを返しません、それらを取得するために {{jsxref("Object.getOwnPropertySymbols()")}} を使うことができます。
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" }
JSON.stringify()
JSON.stringify()
を使用するとき、シンボルをキーとしたプロパティは完全に無視されます。
JSON.stringify({[Symbol('foo')]: 'foo'}) // '{}'
詳しくは {{jsxref("JSON.stringify()")}} を見てください。
シンボルラッパーオブジェクトがプロパティキーとして使用されている場合、このオブジェクトはそのラップされたシンボルを強制的に使用します。
let sym = Symbol('foo') let obj = {[sym]: 1} obj[sym] // 1 obj[Object(sym)] // still 1
仕様書 |
---|
{{SpecName('ESDraft', '#sec-symbol-objects', 'Symbol')}} |
{{Compat("javascript.builtins.Symbol")}}