ES 6ノート(六)SymbolとSymbolの属性を深く理解する


主な知識点:シンボル値の作成、シンボル値の使用、シンボル値の共有、シンボル値の変換.シンボル値のプロパティと有名なシンボルの取得
『ES 6を深く理解する』ノートカタログ
ES 5のオブジェクト属性名は文字列であり、属性名の競合を引き起こしやすい.たとえば、他の人が提供したオブジェクトを使用しますが、このオブジェクトに新しいメソッド(mixinモード)を追加したい場合は、新しいメソッドの名前が既存のメソッドと競合する可能性があります.各属性の名前がユニークであることを保証するメカニズムがあれば、属性名の衝突を根本的に防止することができます.これがES 6がSymbolを導入した理由です.
ES 6は、ユニークな値を表す新しい元のデータ型Symbolを導入した.JavaScript言語の7番目のデータ型で、最初の6つはundefined、null、Boolean値(Boolean)、文字列(String)、数値(Number)、オブジェクト(Object)です.

シンボル値の作成

let firstName = Symbol();
let person = {};
person[firstName] = "Nicholas";
console.log(person[firstName]); // "Nicholas"
console.log(firstName ); // Symbol()
typeof firstName //"symbol"

シンボル値は基本タイプの値であるため、new Symbol()を呼び出すとエラーが発生します.newを通して
Object(yourSymbol)はシンボルインスタンスを作成しますが、これがどのような役割を果たすかは不明です.
Symbol関数はまた、シンボル値を記述するための追加のパラメータを受け入れることができ、この記述は対応する属性にアクセスするために使用されず、デバッグに使用することができる.
let firstName = Symbol("first name");
let person = {};
person[firstName] = "Nicholas";
console.log("first name" in person); // false
console.log(person[firstName]); // "Nicholas"
console.log(firstName); // "Symbol(first name)"

シンボル値の使用


「属性名を計算する必要がある」を任意に使用できる場合には記号を使用してもよいし、Objectでもよい.DefineProperty()またはObject.defineProperties()呼び出しで使用します.
let firstName = Symbol("first name");
//             
let person = {
[firstName]: "Nicholas"
};
//         
Object.defineProperty(person, firstName, { writable: false });
let lastName = Symbol("last name");
Object.defineProperties(person, {
    [lastName]: {
        value: "Zakas",
        writable: false
    }
});
console.log(person[firstName]); // "Nicholas"
console.log(person[lastName]); // "Zakas"

シンボル値の共有


アプリケーションで2つの異なるオブジェクトタイプで同一のシンボル属性を使用する必要がある場合、Symbolを使用します.for()共有シンボル値を作成する;Symbol.for()メソッドは、ターゲットシンボル値の識別子として単一の文字列タイプのパラメータのみを受け入れ、このパラメータもシンボルの記述情報となる.
let uid = Symbol.for("uid");
let object = {};
object[uid] = "12345";
console.log(object[uid]); // "12345"
console.log(uid); // "Symbol(uid)"

まずグローバルシンボルレジストリを検索し、既存の場合は既存のシンボル値を返します.そうでなければ、新しいシンボル値が作成され、キー値を使用してグローバルシンボルレジストリに記録され、新しいシンボル値が返されます.
let uid = Symbol.for("uid");
let object = {
    [uid]: "12345"
};
console.log(object[uid]); // "12345"
console.log(uid); // "Symbol(uid)"
let uid2 = Symbol.for("uid");
console.log(uid === uid2); // true
console.log(object[uid2]); // "12345"
console.log(uid2); // "Symbol(uid)"

Symbol.keyFor()メソッドは、グローバルシンボルレジストリでシンボル値に基づいて対応するキー値を取得します.
let uid = Symbol.for("uid");
console.log(Symbol.keyFor(uid)); // "uid"
let uid2 = Symbol.for("uid");
console.log(Symbol.keyFor(uid2)); // "uid"
//uid3           ,   undefined
let uid3 = Symbol("uid");
console.log(Symbol.keyFor(uid3)); // undefined

シンボル値の変換


タイプ変換はJS言語の重要な一部であり、あるデータ型を非常に柔軟に別のタイプに変換することができる.しかしながら、シンボルタイプは、他のタイプがシンボル値との合理的な等価性に欠けているため、特にシンボル値が文字列値または数値に変換できないため、論理演算子ではtrueに等価とみなされるため、変換時に非常に柔軟ではない.
let uid = Symbol.for("uid"),
desc = uid + ""; //     !
//   console.log()           ,                 String()         。          String()           
let uid = Symbol.for("uid"),
desc = String(uid);
console.log(desc); // "Symbol(uid)"

シンボル属性の取得


Object.keys()とObject.getownPropertyName()メソッドは、オブジェクトのすべての属性名を取得できますが、シンボルタイプの属性を返すことはできません.ES 6はObjectを追加します.getownPropertySymbols()メソッドを使用して、オブジェクトのシンボルタイププロパティを取得できます.Object.getownPropertySymbols()メソッドは、オブジェクト固有の属性名のシンボル値を含む配列を返します.
let uid = Symbol.for("uid");
let object = {
    [uid]: "12345"
};
let symbols = Object.getOwnPropertySymbols(object);
console.log(symbols.length); // 1
console.log(symbols[0]); // "Symbol(uid)"
console.log(object[symbols[0]]); // "12345"