この記事では、ECMAScript7 仕様の instanceof 演算子について詳しく説明します (例を示します)。必要な方は参考にしてください。
この記事では、ECMAScript7仕様のinstanceof演算子を中心に説明します。
「有名な」シンボルとは、Symbol オブジェクト上で定義された組み込みのシンボルを指します。 ECMAScript7 は、@@name の形式を使用してこれらの組み込みシンボルを参照します。たとえば、以下で説明する @@hasInstance は、実際には Symbol.hasInstance です。
O インスタンスオブ C は、内部的に InstanceofOperator(O, C) 抽象操作を呼び出します。 この抽象操作の手順は次のとおりです。 C の場合、データ型がオブジェクトではないため、型エラー例外がスローされます。
instOfHandler を GetMethod(C, @@hasInstance) とすると、おおよそのセマンティクスは @@hasInstance の値を取得します。オブジェクト C の属性;
instOfHandler の値が未定義でない場合:
ToBoolean(? Call(instOfHandler, C, « O »)) の結果を返します。 instOfHandler(O) を実行し、呼び出し結果を強制的にブール型に戻すことです。
C を呼び出すことができない場合は、型エラーの例外をスローします。
OrdinaryHasInstance(C, O) の結果を返します。
OrdinaryHasInstance(C, O)
C を呼び出すことができない場合は、false を返します。
C に内部スロット [[BoundTargetFunction]] がある場合:
BC を C の内部スロット [[BoundTargetFunction]] の値と等しくします。
Return InstanceofOperator(O, BC) 結果;
O の型がオブジェクトでない場合、false を返します。
P を Get(C, "prototype") とすると、おおよそのセマンティクスは値を取得します。 of C.prototype;
P のデータ型がオブジェクトでない場合は、型エラー例外をスローします。
次の手順を繰り返します。
O を O と等しくします。 [[GetPrototypeOf]]() 結果として、おおよそのセマンティクスは O のプロトタイプ オブジェクトを取得することになります。
O が null に等しい場合、
If の結果は false になります。 (P, O) が true の場合、true を返します。
SameValue 抽象操作は、JavaScript の ==、=== を参照し、Object.js() の Object.is() は、この抽象操作の結果を使用します。
上記の手順 2 から、C がバインド関数の場合、C によってバインドされたターゲット関数に対して InstanceofOperator(O, BC) 操作が再実行されることがわかります。
上記の手順 6 からわかるように、オブジェクト O のプロトタイプ オブジェクトが繰り返し取得され、その後、true が返されるまで、プロトタイプ オブジェクトと C のプロトタイプ属性が等しいかどうかが比較されます。等しい場合、または O が null になる場合、つまり、プロトタイプ チェーン全体が false を返します。
Function.prototype[@@hasInstance](V)
ECMAScript7仕様では、Functionのprototype属性に@@hasInstance属性が定義されています。 Function.prototype[@@hasInstance](V) の手順は次のとおりです:
F をこの値と等しくします;
OrdinaryHasInstance(F, V) の結果を返します。
つまり、デフォルトでは、instanceof のセマンティクスは同じであり、それらはすべて OrdinaryHasInstance(F, V) の結果を返すことがわかります。なぜデフォルトでそう言われるのでしょうか? Function.prototype[@@hasInstance] メソッドをオーバーライドして、instanceof の動作をカスタマイズできるためです。
例
function A () {} function B () {} var a = new A a.__proto__ === A.prototype // true a.__proto__.__proto__ === Object.prototype // true a.__proto__.__proto__.__proto__ === null // true a instanceof A // true a instanceof B // false
A のインスタンスの場合、最初のサイクルでは、P は A.prototype です。このとき、a のプロトタイプ オブジェクト a._proto__ は A.prototype、つまりステップ内の O は A.prototype なので、
#インスタンス オブ B の場合、P は B.prototype になります。 、最初のループでは、a のプロトタイプ オブジェクト a._proto__ は A.prototype であり、P と等しくありません。2 番目のループを実行します。この時点では、O は a.__proto__.__proto__ で、これは Object.prototype であり、等しくありません。 3 番目のループ、この時点では O は a.__proto__.__proto__.__proto__ であり、null です。つまり、プロトタイプ チェーンが走査されているため、false が返されます。 上記の例に従います:A.prototype.__proto__ = B.prototype a.__proto__ === A.prototype // true a.__proto__.__proto__ === B.prototype // true a.__proto__.__proto__.__proto__ === Object.prototype // true a.__proto__.__proto__.__proto__.__proto__ === null // true a instanceof B // true
function A () {} var a = new A a instanceof A // true A[Symbol.hasInstance] = function () { return false } a instanceof A // ?
在chrome浏览器测试了一下,发现还是输出true。然后看了一下ECMAScript6的文档,
ECMAScript6文档里面还没有规定可以通过@@hasInstance改变instanceof的行为,所以应该是目前chrome浏览器还没有实现ECMAScript7中的instanceof操作符的行为。
总结
本文主要讲解ECMAScript7规范中的instanceof操作符,希望大家能有所收获。
以上がECMAScript7仕様のinstanceof演算子の詳細な説明(例付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。