ホームページ  >  記事  >  ウェブフロントエンド  >  ECMAScript7仕様のinstanceof演算子の詳細な説明(例付き)

ECMAScript7仕様のinstanceof演算子の詳細な説明(例付き)

不言
不言オリジナル
2018-09-17 14:01:431590ブラウズ

この記事では、ECMAScript7 仕様の instanceof 演算子について詳しく説明します (例を示します)。必要な方は参考にしてください。

この記事では、ECMAScript7仕様のinstanceof演算子を中心に説明します。

予備知識

有名なシンボル

「有名な」シンボルとは、Symbol オブジェクト上で定義された組み込みのシンボルを指します。 ECMAScript7 は、@@name の形式を使用してこれらの組み込みシンボルを参照します。たとえば、以下で説明する @@hasInstance は、実際には Symbol.hasInstance です。

InstanceofOperator(O, C)

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)

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)

上記の InstanceofOperator(O, C) 抽象操作のステップ 2 と 3 から、C が上で定義されているか、または@ @hasInstance 属性を継承すると、手順 4 と 5 を行わずに属性の値が呼び出されます。手順 4 と 5 の目的は、@@hasInstance メソッドを実装していないブラウザと互換性を持たせることです。関数が @@hasInstance 属性を定義または継承していない場合は、デフォルトの instanceof セマンティクスが使用されます。これは、OrdinaryHasInstance(C, O) 抽象操作で記述されるステップです。

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

これは、OrdinaryHasInstance(C, O) のステップ 6 からわかります。

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
上記の例では、B.prototype を a のプロトタイプ チェーン内のリンクに設定し、B のインスタンスが OrdinaryHasInstance(C, O)のステップ6の2回目のループではtrueが返されました。

OrdinaryHasInstance(C, O) の 2 番目のステップから、バインド関数の動作が通常の関数の動作とは異なることがわかります。上の例では、B.prototype は未定義です。したがって、バインド関数で動作するinstanceofの戻り値は、実際にはバインドされたターゲット関数で動作する戻り値であり、基本的にバインド関数とは何の関係もありません。

InstanceofOperator(O, C) のステップ 2 と 3 からわかるように、プロトタイプの @@hasInstance メソッドをオーバーライドすることで、instanceof の動作をカスタマイズできます。
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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。