ES 6学習-新しい文法:Symbols-Symbol.toPrimitive,Symbol.hasInstance,Symbol.toStringTag,Symbol.species

4120 ワード

この4つにはSymbolはありませんiteratorはよくありますが、ブラウザがこれらのwell-known symbolsをサポートしているわけではないので、Kinomaでこれらの特性をテストする必要があります.
まず簡単なSymbolを見てみましょうtoStringTag:
		function Obj(){
		}
		
		Obj.prototype[Symbol.toStringTag] = "-Obj-";
		
		let o1 = new Obj(),o2 = new Obj();;
		trace(o1+"
");//[object -Obj-] o2[Symbol.toStringTag] = "-o2-Obj-"; trace(o2+"
");//[object -o2-Obj-] trace({} + "
");//[object Object] trace(Object.prototype.toString.call(o1)+"
");//[object -Obj-] trace(Object.prototype.toString.call(o2)+"
");//[object -o2-Obj-] trace(Object.prototype.toString.call({})+"
");//[object Object]

上記のコードにより、ES 6では検出対象タイプに対してより柔軟な特性を提供しており、すべての対象が[object Object]ではなく、自分でカスタマイズすることができます.
続いてSymbol.hasInstance、このsymbolはinstanceofオペレータを制御するために使用されます.instanceofの詳細については、ここを参照してください.
例を見てみましょう.
		function Circle(r){
			this.r = r;
		}
		
		Circle[Symbol.hasInstance] = function(inst){
			return inst.r >= 0  && inst.r <= 10;// 0-10 
		}
		
		
		var c1 = new Circle(5),c2 = new Circle(10),c3 = new Circle(15);
		trace((c1 instanceof Circle) + "
");//true trace((c2 instanceof Circle) + "
");//true trace((c3 instanceof Circle) + "
");//false

ここでよく見ると、このsymbolはCircleのprototypeではなくCircleに定義する必要があります.ES 5以降でもObjectを用いることができる.definePropertyが解決します.
Object.defineProperty( Circle, Symbol.hasInstance, {
        value: function(inst) {
            return inst.r >= 0  && inst.r <= 10;
        }
} );

見に来たspecies、このインタフェースは面白くて、説明しにくいです.このように、私たちはArrayのいくつかの方法を使う時、例えばmap、sliceは新しい配列を返して、この過程はみんなが当たり前だと思っているかもしれませんが、実際に戻った結果は制御することができて、通過したのはSymbolです.species、実際にコードを書く中で、このsymbolを使う機会は本当に少ないかもしれません.
次に例を示します.
		class MyArray1 extends Array {
			static get [Symbol.species]() { 
				return Array;
			}
		}
		
		class MyArray2 extends Array {
		}
		
		let result1 = new MyArray1().map(x => x);
		trace(result1 instanceof Array); // true
		
		let result2 = new MyArray2().map(x => x);
		trace(result2 instanceof MyArray2); // true

ES 6では、内蔵クラスはすべて継承可能であり、MyArray 1でSymbolが上書きされている.speciesが実装され、Arrayが返されるので、mapから出てくる新しい配列はMyArrayタイプではなくArrayタイプです.次に、仕様のmapの説明を簡単に見てみましょう.22.11.3.15章では、
7. Let A be ArraySpeciesCreate(O, len).
方法ArraySpeciesCreate 9.4.2.3、章:
6. If isArray is true, then     d. If Type(C) is Object, then         i. Let C be Get(C, @@species).この大まかな過程を見たでしょう.配列のmap、slice、filter、splice、concatの方法はすべてこのような過程です.もちろん、他のオブジェクトのいくつかのAPIもspeciesに役立つ場合があります.
たぶんこれがあればいいと知っていて、本当に使うところはそんなに多くないと思います.
最後にSymbolを見てtoPrimitive、このsymbolは参照タイプと値タイプの演算に関係しています.演算するとき、参照タイプには強制変換のプロセスがあり、このインタフェースで制御できることを知っています.
		var arr = [1,2,3,4,5];
		trace(arr + 10 + "
"); // 1,2,3,4,510 arr[Symbol.toPrimitive] = function(hint) { if (hint == "default" || hint == "number") { // sum all numbers return this.reduce( function(acc,curr){ return acc + curr; }, 0 ); } }; trace(arr + 10); // 25

hint値は文字列で、default、number、stringの3つがあります.一般的に+リンク演算子がdefaultに入力され、乗算などの演算子がnumberに入力され、String(str)がstringに入力され、円形に対する簡単な操作の例を見てみましょう.
		function Circle(r){
			this.r = r;
		}
		
		Circle.prototype[Symbol.toPrimitive] = function(hint){
			if(hint == "default" || hint == "number"){
				return this.r;
			}
			else{
				return this.r * this.r;
			}
		}
		
		var c1 = new Circle(5),c2 = new Circle(10);
		
		var c3 = new Circle(c1 + c2),c4 = new Circle(c2 - c1),c5 = new Circle(c1 * c2);
		
		trace(String(c1) + "
");//25 trace(String(c2) + "
");//100 trace(String(c3) + "
");//225 trace(String(c4) + "
");//25 trace(String(c5) + "
");//2500

上の手順はC++やSwiftのオペレータのリロードに似ていると思いますか?実はこのtoPrimitiveプロセスはJS内部にずっとありますが、ES 6で暴露されただけで、プログラマーがこのプロセスをカスタマイズすることができます.JSはますます強くなりましたが、ますます複雑になりました.
*以上のすべてのコードはKinoma Studioでテストに合格しました.