javascript basics #7 Symbol type

16931 ワード

javascript basics #7 Symbol type
このヒントはJavaScriptですinfo/symbolで作成します.
仕様によっては、JavaScriptオブジェクトアイテムの鍵は、StringSymbolのいずれかにのみ指定できます.数字はだめで、ブール値もだめです.
これまでString万しか使われていませんでした.では、Symbolの長所を見てみましょう.

Symbolとは?

Symbolは一意の識別子です.

Symbolの作成方法

let id = Symbol();

上記のようにSymbolを作成できます.
Symbolを作成するときに、descriptionを作成することもできます.これをsymbol nameと呼びます.

Symbolは一意の識別子であり、同じ記述(symbol name)を有していても異なる値である.descriptionはラベルとしてのみ機能し、コンテンツには影響しません.
例えば、以下に同じ説明を有する2つの要素があるが、それらは等しくない.
let id1 = Symbol("id");
let id2 = Symbol("id");

alert(id1 == id2); // false
rubyのような言語(symbolというキーワードを使用する)を熟知している場合は、JavaScriptのsymbolと混同しないように注意してください.JavaScriptの記号は、他の言語の記号とは異なります.

Symbolは文字列に自動的に変換されません


JavaScriptのほとんどの数値は、文字列への暗黙的な変換をサポートします.ただし、Symbolでは文字列自動変換はサポートされていません.
したがって、以下に示すように、alertコードを記述するとエラーが発生する.
let id = Symbol("id");
alert(id);

自動変換がサポートされていないのは、「languard」の言語乱用を防ぐためだ.
Symbolを出力する場合は、.toString()を直接貼り付けてください.
let id = Symbol("id");
alert(id.toString());
またはsymbol.descriptionを使用することができる.
alert(id.description);

非表示のアイテム群の作成


Symbolでは、非表示のプロパティを作成できます.他のコードは、この非表示のプログラムに偶然アクセスまたは上書きすることはできません.
let user = { // 다른 코드에 속함
  name: "John"
};

let id = Symbol("id");

user[id] = 1;

alert( user[id] ); // 심볼을 키로 이용하여 접근 가능
外部からのインポートなど、Third-party Codeにタッチすると、非表示のプロパティ機能が便利です.
既存のThird-partで作成されたオブジェクトのプロジェクト名を考慮する必要はありません.必要な新しいプロジェクトを任意に登録したり、他の場所でうっかりアクセスしたりする心配はありません.
// ...
let id = Symbol("id");

user[id] = "Some Value";

コンポーネントをオブジェクトツリーに配置する

let id = Symbol("id");

let user = {
  name: "John",
  [id]: 123
};

for in Symbol Property省略

for..inサイクルでSymbol Propertyを省略します.
let id = Symbol("id");
let user = {
  name: "John",
  age: 30,
  [id]: 123
};

for (let key in user) alert(key); // name, age without symbol

// the direct access by the symbol works
alert( "Direct: " + user[id] );
Object.keys(user)でもSymbol Propertyは現れません.したがって、Symbolプロジェクトは、スクリプトまたはライブラリループのいずれにおいても、オブジェクトに偶然アクセスすることはありません.
逆に、Object.assignを使用してオブジェクトをコピーすると、Symbol投影にコピーされます.
let id = Symbol("id");
let user = {
  [id]: 123
};

let clone = Object.assign({}, user);

alert(clone[id]); // 123
このコードは最初にJavaScriptの意図に従って処理された.通常、オブジェクトをコピーする場合は、すべて投影にコピーします.

グローバルSymbol


以上から分かるように、Symbolは同じ名前を持っているが、それらは異なるSymbolと見なされている.しかし、同じ素子が必要になることもあります."id"という記号を作成し、同じpropertyを指す場合はどうすればいいですか?
グローバルSymbolはSymbol.forをサポートします.この空間をglobal symbol registryと呼ぶ.ここでSymbolを登録し、後でアクセスできます.Symbol.for(key)の形式でこの使い方にアクセスできます.
// read from the global registry
let id = Symbol.for("id"); // if the symbol did not exist, it is created

// read it again (maybe from another part of the code)
let idAgain = Symbol.for("id");

// the same symbol
alert(id === idAgain); // true
この方式はRuby言語で使われるSymbolの形式に似ている.

Symbol.keyFor

Symbol.for(key)が返すSymbolがkeyであれば、Symbol.keyFor(symbol) Symbolに従ってkeyを返します.
// get symbol by name
let sym = Symbol.for("name");
let sym2 = Symbol.for("id");

// get name by symbol
alert( Symbol.keyFor(sym) ); // name
alert( Symbol.keyFor(sym2) ); // id
もちろん、非グローバルシンボル(non-global)を追加するとundefinedに戻りますが、正しく動作しません.
let globalSymbol = Symbol.for("name");
let localSymbol = Symbol("name");

alert( Symbol.keyFor(globalSymbol) ); // name, global symbol
alert( Symbol.keyFor(localSymbol) ); // undefined, not global

alert( localSymbol.description); // name

System Symbol


もう一つはJavaScript内部で使われている"System Symbol"です.fine-tuneを使用して、さまざまな面から私たちのオブジェクトを知ることができます.
有名なSymbol Tableには、次のものがあります.
  • "System Symbol"
  • Symbol.hasInstance
  • Symbol.isConcatSpreadable
  • Symbol.iterator
  • 他など...
  • 例えば、Symbol.toPrimitiveは、Symbol.toPrimitiveobjectに変換することを可能にする.
    言語に関するさまざまな特性を学び、他のSymbolを熟知します.

    サマリ

    primitiveは元のタイプであり、一意の識別子である.Symbolを呼び出すことによって作成することができる.
    同じ名前であっても、Symbol()は常に異なる値とみなされます.同じ名前のSymbolを作成するには、Symbolを使用する必要があります.Symbol.for(key)には、以下の主な使用例があります.
  • 非表示オブジェクトアイテムを作成する場合(Symbolまたはfor...inも必要ありません).
  • JavaScriptの内部で使用するObject.keysを使用してSymbol.*を実装したい場合(後でbuilt-in behaviorsを使用してSymbol.iteratorの値を生成します)、iterableを使用してSymbol.toPrimitiveを変換してみます.
    技術的には、object-to-primitiveは100%隠されていない.Symbol、すなわちbuilt-in Methodを使用して、対象スキームのすべてのObject.getOwnPropertySymbol(obj)を得ることができる.また、Symbolは、Reflect.ownKeys(obj)によって記述されたすべてのPropertyを返す.しかし、ほとんどのライブラリ、Symbol、およびbuilt-in functionsでは、これらの方法は使用されません.