浅いES 6新規タイプSymbol

4234 ワード

1、Symbol概要
JavaScriptベースのデータタイプは6種類あります.Unidefined、Null、Boolean、String、Number、Object.
ES 6には一つのデータタイプが追加されました.Symbolはユニークな値を表し、Symbolの最大の用途はオブジェクトを定義するための唯一の属性名です.
ES 5のオブジェクト属性名はすべて文字列であり、属性名の衝突を引き起こしやすい.他の人が提供するオブジェクトを使用しているが、新しい方法(mixinモード)を追加したい場合、新しい方法の名前は既存の方法と競合する可能性がある.したがって、属性名の衝突を防ぐためには、各属性の名前がユニークであることを保証する必要があります.これがES 6がSymbolを導入した理由です.
Symbol値はSymbol関数により生成される.
var symbol1 = Symbol();
var symbol2 = Symbol("Alice");
console.log(symbol1, symbol2) //   :Symbol() Symbol(Alice)
typeof演算子はSymbolタイプの値に使用され、smbolに戻ります.
console.log(typeof Symbol("Alice")) //   :symbol
Symbolタイプの値はユニークな値であり、Symbol関数のパラメータは現在のSymbol値の記述のみを表しているので、同じパラメータのSymbol関数の戻り値は等しくない.
console.log(Symbol() === Symbol()); //   :false
console.log(Symbol("Alice") === Symbol("Alice")); //   :false
Symbolは構造関数ではなく、new Symbolを使えばエラーが発生します(Symbolは元のタイプの値で、対象ではありません).
var symbol = new Symbol(); //   :TypeError
Symbol値は対象ではないので、属性を追加することはできません.
var symbol = Symbol();
symbol.name = "Alice"; //   :TypeError
Symbol値は他のタイプの値とは演算できません.
console.log(Symbol('Alice') + "Bruce"); //   
Symbol値は、明示的に文字列に変換しても良いし、ブール値に変換しても良いですが、数値に変換することはできません.
var symbol = Symbol("Alice");
console.log(symbol.toString()); //   :Symbol(Alice)
console.log(Boolean(symbol)); //   :Symbol(Alice)
if (symbol)
	console.log("YES"); //   :Yes
console.log(Number(symbol)); //   :TypeError
2、対象属性名であるSymbol
各Symbol値は等しくないので、Symbol値がオブジェクトの属性名に使用できることを意味し、同名の属性が出現しないことを保証します.これは一つのオブジェクトが複数のモジュールで構成される場合に非常に有用で、あるキーが誤って書き換えられたり上書きされたりするのを防ぐことができます.
オブジェクトの属性名は、元の文字列と新しいSymbolタイプの2種類があります.すべての属性名はSymbolタイプに属しており、他の属性名と衝突しないことを保証できます.
四角括弧構造とObject.definePropertyにより、オブジェクトの属性名をSymbol値に指定します.
方法1:
var name = Symbol();
var obj = {
	[name]: "Alice"
};
方法二:
var name = Symbol();
var obj = {};
obj[name] = "Alice";
方法三:
var obj = {};
Object.defineProperty(obj, name, { value: 'Alice' });
オブジェクトの内部で、Symbol値を使用して属性を定義する場合、Symbol値は四角い括弧に入れなければなりません.四角い括弧に入れない場合、この属性名は文字列であり、代表的なSymbol値ではありません.
var name = Symbol();
var obj1 = {
	[name]: "Alice"
};
var obj2 = {
	name: "Bruce"
};
console.log(obj1.name); //   :undefined
console.log(obj1[name]); //   :Alice
console.log(obj2.name); //   :Bruce
console.log(obj2[name]); //   :undefined
Symbol値が対象属性名の場合は、ポイント演算子は使用できません.点演算子の後はいつも文字列なので、nameが識別名として指す値は読み取られません.属性名は実はSymbol値ではなく文字列です.
var obj = {};
var name = Symbol();
obj.name = 'Alice';
console.log(obj.name);
console.log(obj[name]);
console.log(obj['name']);
3、対象関数名であるSymbol
var func = Symbol();
var obj = {
	func: function() {
		console.log("YES");
	}
};
obj.func(); //   :YES
4、オブジェクト属性を取得する2つの方法
1) Object.getOwn PropertySymbors()の方法
Symbolタイプのみを含む属性名の配列を返します.
2) Object.getOwn PropertyNames()の方法
文字列タイプのみを含む属性名の行列を返します.
var obj = {};
var age = Symbol("age");
var job = Symbol("job");
obj[age] = "Alice";
obj[job] = "student";
obj.age = 23;
var symbols = Object.getOwnPropertySymbols(obj);
var names = Object.getOwnPropertyNames(obj);
console.log(symbols.length); //   :2
console.log(symbols); //   :[Symbol(age), Symbol(job)]
console.log(obj[symbols[0]]); //   :Alice
console.log(names.length); //   :1
console.log(obj[names[0]]); //   :23
5、Symbol.for()とSymbol.keyFor()の方法
1) Symbol.for()方法
一例モードと同様に、まずグローバルにおいて、このパラメータを名称とするSymbol値があるかどうかを検索し、ある場合はSymbol値を返します.そうでなければ、新規作成して、このパラメータを名前とするSymbol値を返します.
var symbol1 = Symbol.for('Alice');
var symbol2 = Symbol.for('Alice');
console.log(symbol1 === symbol2) //   :true
2) Symbol.keyFor()方法
作成されたSymbolタイプ値のkeyを返します.実質的にSymbolが作成されたかどうかを検出します.
var symbol1 = Symbol.for("Alice");
console.log(Symbol.keyFor(symbol1)); //   :"Alice"
var symbol2 = Symbol("Alice");
console.log(Symbol.keyFor(symbol2)); //   :undefined