JavaScript プログラミング講座

 

Symbol について

 


■ Symbol について

 
ECMAScript 6 世代の機能です。
 
■ Symbol オブジェクトについて
 
Symbol オブジェクトは、リファレンス型に該当します。
 
シンボル自体には、特筆すべき機能は何もありません。
 
Object を継承していますが、連想配列としては機能しません。
 
typeof 演算子を使用すると、"symbol" という文字列が得られます。
 
■ Symbol オブジェクトの種類について
 
ローカルなシンボル」と「グローバルなシンボル」の2種類があります。
 
■シンボルプロパティとして活用する
 
任意のオブジェクトに、シンボルプロパティを追加する事ができます。
 


 

ローカルなシンボルについて

 
 


■ローカルな Symbol オブジェクトを作成する

 
Symbol() 関数を使用します。
 
Symbol( "description" ) :Symbol
第01引数(略可)String好きな説明文を指定(デバッグ用)
戻り値 Symbol新しい Symbol オブジェクトが得られる。
 
■第01引数(説明文)
 
通常は、指定する必要はありません。
 
第01引数の指定は、新しい Symbol オブジェクトに影響しません。
 
開発者が、デバッガなどから、Symbol の利用目的を確認する為に利用します。
 
■戻り値(Symbol)
 
必ずユニーク(唯一)な、Symbol オブジェクトが生成されます。
 
■使用例
 
Symbol オブジェクトを作成する

// ------------------------------------------------------------
// Symbol オブジェクトを作成する
// ------------------------------------------------------------
var symbol_obj0 = Symbol();
var symbol_obj1 = Symbol();

// 出力テスト
console.log(symbol_obj0);
console.log(symbol_obj1);

// ------------------------------------------------------------
// Symbol オブジェクトを作成する(デバッグ用の説明文付き)
// ------------------------------------------------------------
var symbol_obj2 = Symbol( "説明文A" );
var symbol_obj3 = Symbol( "説明文B" );

// 出力テスト
console.log(symbol_obj2);
console.log(symbol_obj3);
 


 

グローバルなシンボルについて

 
 


■グローバルな Symbol オブジェクトを作成する

 
Symbol.for() メソッドを使用します。
 
Symbol.for( "key" ) :Symbol
第01引数 Stringキー情報(識別名)を指定
戻り値 Symbolグローバルな Symbol オブジェクトが得られる。
 
■第01引数(キー情報)
 
キー情報(識別名)を指定します。
 
ユニーク(唯一)な識別名を指定した場合、必ず新しい Symbol オブジェクトが得られます。
 
以前と同じ識別名を指定した場合、最初に作成した Symbol オブジェクトが得られます。
 
■使用例
 
グローバルな Symbol オブジェクトを作成する

// ------------------------------------------------------------
// グローバルな Symbol オブジェクトを作成する
// ------------------------------------------------------------
var symbol_a0 = Symbol.for( "key_a" );
var symbol_b0 = Symbol.for( "key_b" );
var symbol_c0 = Symbol.for( "key_c" );

// 出力テスト
console.log(symbol_a0);
console.log(symbol_b0);
console.log(symbol_c0);

// ------------------------------------------------------------
// 以前と同じ Symbol オブジェクトを取得する
// ------------------------------------------------------------
var symbol_a1 = Symbol.for( "key_a" );
var symbol_b1 = Symbol.for( "key_b" );
var symbol_c1 = Symbol.for( "key_c" );

// 出力テスト
console.log(symbol_a0 == symbol_a1); // true
console.log(symbol_b0 == symbol_b1); // true
console.log(symbol_c0 == symbol_c1); // true

console.log(symbol_a0 == symbol_b0); // false
console.log(symbol_a0 == symbol_c0); // false
console.log(symbol_b0 == symbol_c0); // false
 

■グローバルな Symbol オブジェクトから、キー情報(識別名)を取得する

 
Symbol.keyFor() メソッドを使用します。
 
ローカルな Symbol オブジェクトを指定すると失敗します。
 
この場合、undefined 値が得られます。
 
Symbol.keyFor( symbol ) :String
第01引数 Symbolグローバルな Symbol オブジェクトを指定
戻り値 Stringキー情報(識別名)が得られる。失敗した場合 undefined 値が得られる
 
■使用例
 
グローバルな Symbol オブジェクトから、キー情報(識別名)を取得する

// ------------------------------------------------------------
// グローバルな Symbol オブジェクトを作成する
// ------------------------------------------------------------
var symbol_a = Symbol.for( "key_a" );
var symbol_b = Symbol.for( "key_b" );
var symbol_c = Symbol.for( "key_c" );

// ------------------------------------------------------------
// グローバルな Symbol オブジェクトから、キー情報(識別名)を取得する
// ------------------------------------------------------------
var name_a = Symbol.keyFor( symbol_a );
var name_b = Symbol.keyFor( symbol_b );
var name_c = Symbol.keyFor( symbol_c );

// 出力テスト
console.log(name_a); // "key_a"
console.log(name_b); // "key_b"
console.log(name_c); // "key_c"


// ------------------------------------------------------------
// ローカルな Symbol オブジェクトを作成する
// ------------------------------------------------------------
var symbol_d = Symbol( "説明文D" );

// ------------------------------------------------------------
// キー情報(識別名)の取得を試みる(ローカルな Symbol オブジェクトなので失敗する)
// ------------------------------------------------------------
var name_d = Symbol.keyFor( symbol_d );

// 出力テスト
console.log( name_d ); // undefined
 


 

シンボルプロパティについて

 


■シンボルプロパティとは?

 
Symbol オブジェクトは、任意のオブジェクトのキーとして利用できます。
 
こうして追加されるプロパティは、シンボルプロパティと呼ばれます。
 
■従来の API との互換性について
 
シンボルプロパティは、従来の方法で検出する事はできません。
 
例えば、for..in 文を使用して検出する事はできません。
 
例えば、Object.keys() メソッドを使用して、検出する事はできません。
 
これにより、旧世代のライブラリ資産は、そのまま安全に利用できます。
 
イテレーターなどの次世代の仕様と干渉する事はありません。
 

■シンボルプロパティにアクセスする

 
■シンボルプロパティにアクセスする
 
配列アクセス演算子を使用します。
 
ドットアクセス演算子は利用できません。
 
任意のオブジェクトにシンボルプロパティを追加する

// ------------------------------------------------------------
// Object オブジェクトを作成する
// ------------------------------------------------------------
var obj = new Object();

// ------------------------------------------------------------
// Symbol オブジェクトを作成する
// ------------------------------------------------------------
var symbol_a = Symbol();
var symbol_b = Symbol();
var symbol_c = Symbol();

// ------------------------------------------------------------
// シンボルプロパティを追加して、値をセットする
// ------------------------------------------------------------
obj[symbol_a] = 123;
obj[symbol_b] = "あいう";
obj[symbol_c] = {a:0,b:1,c:2};

// ------------------------------------------------------------
// シンボルプロパティから値を取得する
// ------------------------------------------------------------
var value_a = obj[symbol_a];
var value_b = obj[symbol_b];
var value_c = obj[symbol_c];

// ------------------------------------------------------------
// 出力テスト
// ------------------------------------------------------------
console.log( value_a ); // 123
console.log( value_b ); // "あいう"
console.log( value_c ); // {a:0,b:1,c:2}
 
■シンボルプロパティを削除する
 
シンボルプロパティを削除するには、delete 文を使用します。
 
任意のオブジェクトから、シンボルプロパティを削除する

// ------------------------------------------------------------
// Object オブジェクトを作成する
// ------------------------------------------------------------
var obj = new Object();

// ------------------------------------------------------------
// Symbol オブジェクトを作成する
// ------------------------------------------------------------
var symbol_a = Symbol();
var symbol_b = Symbol();
var symbol_c = Symbol();

// ------------------------------------------------------------
// シンボルプロパティを追加して、値をセットする
// ------------------------------------------------------------
obj[symbol_a] = 123;
obj[symbol_b] = "あいう";
obj[symbol_c] = {a:0,b:1,c:2};

// ------------------------------------------------------------
// シンボルプロパティを削除する
// ------------------------------------------------------------
delete obj[symbol_a];
delete obj[symbol_b];
delete obj[symbol_c];
 

■オブジェクトからシンボルプロパティをまとめて取得する

 
Object.getOwnPropertySymbols() メソッドを使用します。
 
Object.getOwnPropertySymbols ( オブジェクト ) :Array
第01引数 Objectオブジェクトを指定。
戻り値 ArraySymbol オブジェクトが格納された配列が得られる。
 
■使用例
 
シンボルプロパティのキーとなる Symbol オブジェクトをまとめて取得する

// ------------------------------------------------------------
// Object オブジェクトを作成する
// ------------------------------------------------------------
var obj = new Object();

// ------------------------------------------------------------
// ローカルな Symbol オブジェクトを作成する
// ------------------------------------------------------------
var symbol_a = Symbol( "説明文A" );
var symbol_b = Symbol( "説明文B" );
var symbol_c = Symbol( "説明文C" );

// ------------------------------------------------------------
// グローバルな Symbol オブジェクトを作成する
// ------------------------------------------------------------
var symbol_d = Symbol.for( "key_d" );
var symbol_e = Symbol.for( "key_e" );
var symbol_f = Symbol.for( "key_f" );

// ------------------------------------------------------------
// シンボルプロパティを追加して、値をセットする
// ------------------------------------------------------------
obj[symbol_a] = "value_a";
obj[symbol_b] = "value_b";
obj[symbol_c] = "value_c";
obj[symbol_d] = "value_d";
obj[symbol_e] = "value_e";
obj[symbol_f] = "value_f";

// ------------------------------------------------------------
// シンボルプロパティのキーをまとめて取得する(Symbol オブジェクトのリスト)
// ------------------------------------------------------------
var symbol_list = Object.getOwnPropertySymbols ( obj );

// 出力テスト
console.log(symbol_list); // { length:6 , ...
 

■シンボルプロパティの参照強度について

 
シンボルプロパティは、強参照です。
 
Object.getOwnPropertySymbols() メソッドを利用すると、いつでもキーとなる Symbol オブジェクトにアクセスできます。
 
シンボルプロパティを明示的に削除しなかった場合、キーとなる Symbol オブジェクトと、格納した値は、生存し続けます。
 
オブジェクト自体がガベージコレクションの対象となった場合、シンボルプロパティも連動して消滅します。
 
シンボルプロパティの参照強度を確認する

// ------------------------------------------------------------
// Object オブジェクトを作成する
// ------------------------------------------------------------
var obj = new Object();

// ------------------------------------------------------------
// Symbol オブジェクトを作成する
// ------------------------------------------------------------
var symbol = Symbol();

// ------------------------------------------------------------
// 128 MByte 相当のデータを用意する
// ------------------------------------------------------------
var ary_u8 = new Uint8Array(1024 * 1024 * 128);

// ------------------------------------------------------------
// シンボルプロパティを追加して、値をセットする
// ------------------------------------------------------------
obj[symbol] = ary_u8;

// ------------------------------------------------------------
// 変数に null をセット(シンボルプロパティは消滅しない)
// ------------------------------------------------------------
symbol = null;
ary_u8 = null;

// ------------------------------------------------------------
// Object オブジェクトから Symbol オブジェクトを取得できる
// ------------------------------------------------------------
// シンボルプロパティのキーをまとめて取得する(Symbol オブジェクトのリスト)
var symbol_list = Object.getOwnPropertySymbols ( obj );

// Symbol オブジェクトを取得する
symbol = symbol_list[0];

// ------------------------------------------------------------
// 変数に null をセット(オブジェクト自体が消滅する場合、シンボルプロパティも消滅する)
// ------------------------------------------------------------
obj = null;