【ECMAScript2015(ES6)】後で猫に教えてあげたいES6の「Symbol(シンボル)」
ES6のSymbolがややぼんやりしていたのでいじってみました。
嬉しいことはこちら。
SymbolはObjectのkeyとしてプライベートなpropertyを生成できる
・既存のオブジェクトのプロパティと干渉しない
・意図せずデータが可視されない
・他のコードから追加実行されない
・一意の識別子を作成できる
それを踏まえて以下、遊びます。
[code lang="javascript"]
//Symbol型
const symM = Symbol();
console.log(typeof symM) //"symbol";
//シンボルはユニーク
const symbol1 = Symbol('morita');
const symbol2 = Symbol('morita');
console.log(symbol1 === symbol2)//false
//////////////////////////////////////
//隠蔽度が高いSymbom
//Symbolを使わない例
class fafa {
constructor(name){
this.name = name;
}
}
const name = new fafa("kenji");
console.log(name.name);//"kenji"アクセスできる
console.log(name["name"]);//"kenji"アクセスできる
//////////////////////////////////////
//Symbolを使った例
class fafa2 {
constructor(name){
this.name = Symbol(name);
}
}
const name2 = new fafa2("kenji");
console.log(name2.name)//何も出力されない
console.log(name2["name"])//何も出力されない
//////////////////////////////////////
//module-scoped symbol
var key = Symbol("description");
class MyClass {
constructor(privateData){
this[key] = privateData;
}
someFunc() {
return "data: " + this[key];
}
}
var c = new MyClass("private data")
console.log(key);//取得できない
console.log(c["key"]);//取得できない
console.log(c.someFunc());
//////////////////////////////////////
//obj[key]で列挙されない
var obj = {};
obj[Symbol("a")] = "a";
obj[Symbol.for("b")] = "b";
obj["c"] = "c";
obj.d = "d";
for(var i in obj){
console.log(i);//c d
}
//////////////////////////////////////
//JSON.stringifyで無視される
//無視される
console.log(JSON.stringify({[Symbol("foo")] : "foo"}));
//{}
//通常のは出力される
console.log(JSON.stringify({foo : "foo"}));
//{"foo":"foo"}
//////////////////////////////////////
//プロパティキーとしてのSymbolラッパーオブジェクト
//プロパティキーとしてsymbolラッパーオブジェクトを使うとき、
//このオブジェクトはラッパーされたsymbolを強制されます。
var sym = Symbol("foo");
var obj = {[sym] : 1};
console.log(obj[sym]);//1
console.log(obj[Object(sym)])//1
//////////////////////////////////////
//Symbolラッパーオブジェクトの生成(Symbolコンストラクタをnewで呼ぶことはできない。
//Objectコンストラクタに渡すことでラップしている。型が変わっていることを確認)
var sym = Symbol("foo");
typeof sym; // "symbol"
var symObj = Object(sym);
typeof symObj; // "object"
//このSymbol()はコード全体、ファイルをまたいで使用できない。(global環境にsymbolを生成しない)
//globalに使いたい場合「グローバルsymbolレジストリー」からsymbolを設定し扱う。
//それには下記Symbol.forやSymbol.keyFor()を使う
////////////////////////////////////////
//Symbol.for
const sy1 = Symbol.for("foo"); //新しくSymbolをグローバルに作成
const sy2 = Symbol.for("foo"); //既に作ってあるSymbolが返される、なければ作られる
console.log(sy1 === sy2);//true 同じレジストリから参照したシンボルだから
//グローバルのsymbleは同じだがlocalのシンボルは違う
Symbol.for("bar") === Symbol.for("bar");//true
Symbol("bar") === Symbol("bar"); //false
////////////////////////////////////////
//Symbol.key
var globalSym = Symbol.for("foo");
Symbol.keyFor(globalSym)//グローバルから探す //"foo"
var localSym = Symbol();
Symbol.keyFor(localSym);//undefined
////////////////////////////////////////
//globalでのSymbolの名前衝突をさけている
Symbol.for("mdn.foo");
Symbol.for("mdn.bar");
[/code]
今回のコード