この性質は他の言語にはあまり存在しない概念ですから、もう少しよくみてみましょう。
シンボルはSymbolクラスのコンストラクタを呼ぶことで作成されます。
引数を指定することが出来ます。
sb1 = Symbol() sb2 = Symbol('name')
シンボルはSymbolクラスのコンストラクタを呼ぶ度に新しい値が生成されます。
よって下記コードのように同じ'name'を引数としたとしても、呼び出す度に違う値が生成されます。
sb1 = Symbol() sb2 = Symbol('name') sb3 = Symbol('name') sb2 === sb3 // false Symbol('name') === Symbol('name') // false
let a = Symbol.for('name'); // 新しくシンボルが作られる let b = Symbol.for('name'); // すでに存在すればそのシンボルが返される hm.debuginfo(a == b) // true
let a = Symbol.for('name'); // 新しくシンボルが作られる hm.debuginfo(Symbol.keyFor(a)) // name
const RED = Symbol(); const YELLOW = Symbol(); const BLUE = Symbol(); // … let color = RED; if (color == RED) { hm.debuginfo("色は赤です"); }
このようにすることで、「数値など」と比較し手抜きをすることは不可能となり、
あくまでも RED or YELLOW or BLUE との比較を課すことが出来ます。
classやオブジェクトの特定のプロパティを外部から見えなくするのに使えなくもないですが、
余計にソースが歪みますので、あまりそのような目的に利用するべきではないでしょう。
private目的というよりも、こちらのkeysでは取得させたくないメンバとして利用する、
というのは仕掛けとして有りだと思います。
Symbolはfor...inイテレーションからは見えません。
var obj = {}; obj[Symbol("a")] = "a"; obj[Symbol.for("b")] = "b"; obj["c"] = "c"; obj.d = "d"; for (var i in obj) { hm.debuginfo(i); // 結果 "c" and "d" }
for...in同様、こちらからもSymbolのプロパティは無視されます。
JSON.stringify({[Symbol("foo")]: "foo"}); // '{}'