はじめに
こんにちは、SHOJIです。
JavaScript(ES6)でプライベートプロパティの実装について調べるとSymbolを使った方法がよく出てきます。
本記事では、Symbolとは何なのか?について記載します。
Symbolを用いたPrivate Propertiesの参考記事
stackoverflow.com
Symbolの使用例
Symbolを使わない例(Privateプロパティになっていない状態)
var Dog = (() => {
const propSound = "propSound";
class Dog{
constructor(sound){
this[propSound] = sound;
}
calls(){
console.log(this[propSound]);
}
}
return Dog;
})();
const dog = new Dog("bow-wow");
console.log(dog);
dog["propSound"] = "woof";
dog.calls();
上記のコードはdogインスタンスのsoundを変更できますが、次のSymbolを使う例では外からプロパティを変更できません。
Symbolを使う例(Privateプロパティになった状態1)
var Dog = (() => {
const propSound = Symbol();
class Dog{
constructor(sound){
this[propSound] = sound;
}
calls(){
console.log(this[propSound]);
}
}
return Dog;
})();
const dog = new Dog("bow-wow");
console.log(dog);
dog[Symbol()] = "woof";
dog.calls();
処理終了時点でdogオブジェクトがどうなっているかというと、Symbolが二つ存在しています。
console.log(dog);
Symbolは何をしているのか
mozillaのSymbolのページ(https://developer.mozilla.org/ja/docs/Glossary/Symbol)ではこのような説明がされています。
動的に無名の一意の値を生み出します。シンボルはオブジェクトプロパティとして使用されることがあります。
なるほど、Symbolは必ず一意の値を生成するから
dog[Symbol()] = "woof";
このようにしてもdogインスタンスが元々持っていたSymbolプロパティとは別物とみなされたんですね。これなら処理終了時点でdogオブジェクトにSymbolプロパティが二つ存在している(ように見える)ことにも納得がいきます。
ちなみに、Symbolは文字列を引数に取ることができます。
const propSound = Symbol("sound property");
この引数はあくまで説明書きとしてしか機能しないので、同じ文字列を引数にしたSymbolであっても別の値が生成されます。
console.log(Symbol("sound property") === Symbol("sound property"))