Heim  >  Artikel  >  Web-Frontend  >  Detaillierte Erläuterung des Instanzoperators in der ECMAScript7-Spezifikation (mit Beispielen)

Detaillierte Erläuterung des Instanzoperators in der ECMAScript7-Spezifikation (mit Beispielen)

不言
不言Original
2018-09-17 14:01:431588Durchsuche

Dieser Artikel enthält eine detaillierte Erklärung des Instanzoperators (mit Beispielen) in der ECMAScript7-Spezifikation. Ich hoffe, dass er für Freunde hilfreich ist.

In diesem Artikel wird hauptsächlich der Instanzoperator in der ECMAScript7-Spezifikation erläutert.

Vorkenntnisse

Berühmte Symbole

„Berühmte“ Symbole beziehen sich auf die integrierten Symbole, die im Symbolobjekt definiert sind. ECMAScript7 verwendet die Form von @@name, um auf diese integrierten Symbole zu verweisen. Das unten erwähnte @@hasInstance ist beispielsweise tatsächlich Symbol.hasInstance.

InstanceofOperator(O, C)

O-Instanz von C ruft intern die abstrakte Operation InstanceofOperator(O, C) auf:

Wenn C Der Datentyp ist kein Objekt und es wird eine Typfehlerausnahme ausgelöst.

Lassen Sie instOfHandler gleich GetMethod(C, @@hasInstance). von Objekt C;

Wenn der Wert von instOfHandler nicht undefiniert ist, dann:

gibt das Ergebnis von ToBoolean(? Call(instOfHandler, C, « O »)) zurück um instOfHandler(O) auszuführen und dann das Aufrufergebnis in eine boolesche Rückgabe zu zwingen.

Wenn C nicht aufgerufen werden kann, wird eine Ausnahme vom Typ Fehler ausgelöst.

Das Ergebnis von OrdinaryHasInstance(C, O) zurückgeben.

OrdinaryHasInstance(C, O)

Die abstrakten Operationsschritte von OrdinaryHasInstance(C, O) lauten wie folgt:

Wenn C nicht aufgerufen werden kann, geben Sie false zurück; 🎜 >Wenn C einen internen Slot [[BoundTargetFunction]] hat, dann:

Sei BC gleich dem Wert von Cs internem Slot [[BoundTargetFunction]];

Return InstanceofOperator(O, BC) Das Ergebnis von

Wenn der Datentyp von P kein Objekt ist, wird eine Typfehlerausnahme ausgelöst

Wiederholen Sie die folgenden Schritte:

Sei O gleich O.[[GetPrototypeOf]] () Als Ergebnis besteht die ungefähre Semantik darin, das Prototypobjekt von O zu erhalten.

Wenn O gleich null ist, wird false zurückgegeben.

Wenn das Ergebnis von SameValue(P, O) ist wahr ist, gib wahr zurück.

Abstrakte SameValue-Operationen beziehen sich auf ==, === in JavaScript und Object.is() in Object.js() verwendet das Ergebnis dieser abstrakten Operation.

Aus Schritt 2 oben wissen wir, dass, wenn C eine Bindungsfunktion ist, die InstanceofOperator(O, BC)-Operation auf der durch C gebundenen Zielfunktion erneut ausgeführt wird.

Wie aus dem obigen Schritt 6 ersichtlich ist, wird das Prototypobjekt von Objekt O wiederholt abgerufen und dann das Prototypobjekt und das Prototypattribut von C verglichen, um festzustellen, ob sie gleich sind, bis die Gleichheit erreicht ist Gibt true zurück, oder O wird null, dh die Durchquerung ist abgeschlossen. Die gesamte Prototypenkette gibt false zurück.

Function.prototype[@@hasInstance](V)

Aus den Schritten 2 und 3 der obigen abstrakten Operation InstanceofOperator(O, C) lässt sich erkennen, dass, wenn C oben definiert ist oder erbt das Attribut @@hasInstance, der Wert des Attributs wird aufgerufen, ohne dass die Schritte 4 und 5 ausgeführt werden müssen. Der Zweck der Schritte 4 und 5 besteht darin, mit Browsern kompatibel zu sein, die die @@hasInstance-Methode nicht implementieren. Wenn eine Funktion das Attribut @@hasInstance nicht definiert oder erbt, wird die Standardinstanz der Semantik verwendet, d. h. die Schritte, die durch die abstrakte Operation OrdinaryHasInstance(C, O) beschrieben werden.

In der ECMAScript7-Spezifikation ist das @@hasInstance-Attribut für das Prototypattribut von Function definiert. Die Schritte von Function.prototype[@@hasInstance](V) sind wie folgt:

Sei F gleich diesem Wert;

gibt das Ergebnis von OrdinaryHasInstance(F, V) zurück.

Sie sehen also, dass die Semantik von „instanceof“ standardmäßig dieselbe ist und alle das Ergebnis von „OrdinaryHasInstance(F, V)“ zurückgeben. Warum heißt es standardmäßig? Weil Sie die Methode „Function.prototype[@@hasInstance]“ überschreiben können, um das Verhalten von „instanceof“ anzupassen.

Beispiel

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
Aus Schritt 6 von OrdinaryHasInstance(C, O) ist ersichtlich:

Für eine Instanz von A ist P A.prototype in der ersten Schleife Zu diesem Zeitpunkt ist das Prototypobjekt a._proto__ von a A.prototype, das heißt, O im Schritt ist A.prototype, daher wird true zurückgegeben.

Für eine Instanz von B ist P B.prototype In der ersten Schleife ist das Prototypobjekt a._proto__ von a A.prototype, ungleich P; führt die zweite Schleife aus, zu diesem Zeitpunkt ist O a.__proto__.__proto__, also Object.prototype, ungleich zu P; ausführen Die dritte Schleife, zu diesem Zeitpunkt ist O a.__proto__.__proto__.__proto__, was null ist, das heißt, die Prototypenkette wurde durchlaufen, daher wird false zurückgegeben.

Folgen Sie dem obigen Beispiel:

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
Im obigen Beispiel legen wir B.prototype als Glied in der Prototypenkette von a fest, sodass eine Instanz von B in OrdinaryHasInstance(C, In der zweiten Schleife von Schritt 6 von O) wurde true zurückgegeben.

Aus dem zweiten Schritt von OrdinaryHasInstance(C, O) wissen wir, dass sich das Verhalten der Bindungsfunktion vom Verhalten der gewöhnlichen Funktion unterscheidet:

function A () {}
var B = A.bind()

B.prototype === undefined // true

var b = new B
b instanceof B // true
b instanceof A // true
Wie aus dem ersichtlich ist Im obigen Beispiel ist B.prototype undefiniert. Daher ist das Rückgabeergebnis der auf die Bindungsfunktion wirkenden Instanz tatsächlich der Rückgabewert, der auf die gebundene Zielfunktion wirkt, was im Grunde nichts mit der Bindungsfunktion zu tun hat.

Wie aus den Schritten 2 und 3 von InstanceofOperator(O, C) ersichtlich ist, können wir das Verhalten von Instanzof anpassen, indem wir die Methode @@hasInstance im Prototyp überschreiben:

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操作符,希望大家能有所收获。

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung des Instanzoperators in der ECMAScript7-Spezifikation (mit Beispielen). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn