この投稿はについてでありSymbol()
、私が見つけたり作成したりできる実際の例と、見つけた事実と定義が提供されています。
TLDR;
これSymbol()
は、ECMAScript 6(ES6)のリリースで導入されたデータ型です。
シンボルには2つの興味深い事実があります。
最初のデータ型であり、リテラルを持たないJavaScriptの唯一のデータ型
で定義された変数Symbol()
は一意のコンテンツを取得しますが、実際には非公開ではありません。
データには独自のシンボルがあり、同じデータの場合、シンボルは同じになります。次の段落で詳細を説明します。それ以外の場合はTLRDではありません。:)
シンボルを初期化するにはどうすればよいですか?
1.デバッグ可能な値を持つ一意の識別子を取得するには
次のいずれかの方法で行うことができます。
var mySymbol1 = Symbol();
またはこのように:
var mySymbol2 = Symbol("some text here");
"some text here"
文字列は、シンボルから抽出することができない、それはデバッグ目的のためだけの説明です。シンボルの動作を変更することはありません。ただし、それは可能ですconsole.log
(値はデバッグ用であり、他のログエントリと間違えないようにするため、これは公平です)。
console.log(mySymbol2);
// Symbol(some text here)
2.一部の文字列データのシンボルを取得するには
この場合、symbolの値が実際に考慮され、このようにして2つのシンボルが一意でなくなる可能性があります。
var a1 = Symbol.for("test");
var a2 = Symbol.for("test");
console.log(a1 == a2); //true!
それらのシンボルを「第2タイプのシンボル」と呼びましょう。これらは、「最初のタイプ」のシンボル(つまり、で定義されたシンボル)とは決して交差しませんSymbol(data)
。
次の2つの段落は、最初のタイプのシンボルのみに関係します。
古いデータ型の代わりにシンボルを使用するメリットは何ですか?
まず、標準のデータ型であるオブジェクトについて考えてみましょう。そこでいくつかのキーと値のペアを定義し、キーを指定することで値にアクセスできます。
var persons = {"peter":"pan","jon":"doe"};
console.log(persons.peter);
// pan
ピーターという名前の人が2人いるとしたらどうでしょう。
これを行う:
var persons = {"peter":"first", "peter":"pan"};
あまり意味がありません。
したがって、同じ名前を持つ2人のまったく異なる人の問題であるように見えます。次にnewを参照してみましょうSymbol()
。実生活の人のようなものです。どの人もユニークですが、名前は同じでもかまいません。2人の「人」を定義してみましょう。
var a = Symbol("peter");
var b = Symbol("peter");
これで、同じ名前の2人の異なる人物ができました。私たちの人は本当に違うのですか?彼らです; あなたはこれをチェックすることができます:
console.log(a == b);
// false
そこでどのようなメリットがありますか?
私たちはあなたのオブジェクトに異なる人のために2つのエントリーを作ることができ、それらは決して間違えられません。
var firstPerson = Symbol("peter");
var secondPerson = Symbol("peter");
var persons = {[firstPerson]:"first", [secondPerson]:"pan"};
注:
オブジェクトを文字列JSON.stringify
化すると、Symbolをキーとして初期化されたすべてのペアが削除されることに注意してください。
実行してObject.keys
も、そのようなSymbol()->value
ペアは返されません。
この初期化を使用すると、最初の人と2番目の人のエントリを間違えることは絶対に不可能です。console.log
それらを呼び出すと、2番目の名前が正しく出力されます。
console.log(persons[a]);
// first
console.log(persons[b]);
// pan
オブジェクトで使用すると、列挙不可能なプロパティを定義する場合とどのように異なりますか?
実際、非表示Object.keys
および列挙するプロパティを定義する方法はすでに存在していました。ここにあります:
var anObject = {};
var fruit = "apple";
Object.defineProperty( anObject, fruit, {
enumerable: false,
value: "green"
});
Symbol()
そこにはどんな違いがありますか?違いはObject.defineProperty
、通常の方法で定義されたプロパティを引き続き取得できることです。
console.log(anObject[fruit]); //green
console.log(anObject["apple"]); //green
console.log(anObject.apple); //green
そして、前の段落のようにシンボルで定義されている場合:
fruit = Symbol("apple");
変数を知っている場合にのみ、その値を受け取ることができます。
console.log(anObject[fruit]); //green
console.log(anObject["apple"]); //undefined
console.log(anObject.apple); //undefined
さらに、キーの下に別のプロパティを定義"apple"
すると、オブジェクトは古いプロパティを削除します(ハードコードされている場合、エラーがスローされる可能性があります)。だから、これ以上のリンゴはありません!それは残念だ。前の段落を参照すると、記号は一意であり、Symbol()
一意になるようにキーを定義しています。
型変換とチェック
他のデータ型とは異なり、他のデータ型に変換することは不可能Symbol()
です。
を呼び出すことにより、プリミティブデータタイプに基づいてシンボルを「作成」することができSymbol(data)
ます。
タイプのチェックに関しては、何も変更されません。
function isSymbol ( variable ) {
return typeof someSymbol === "symbol";
}
var a_Symbol = Symbol("hey!");
var totally_Not_A_Symbol = "hey";
console.log(isSymbol(a_Symbol)); //true
console.log(isSymbol(totally_Not_A_Symbol)); //false