361 Stimmen

Was ist der instanceof-Operator in JavaScript?

のことです。 instanceof Schlüsselwort in JavaScript kann beim ersten Mal ziemlich verwirrend sein, da die meisten Leute denken, dass JavaScript keine objektorientierte Programmiersprache ist.

  • Was ist das?
  • Welche Probleme werden damit gelöst?
  • Wann ist es angebracht und wann nicht?

316voto

JonH Punkte 31873

Instanceof

Der Operand auf der linken Seite (LHS) ist das zu testende Objekt, der Operand auf der rechten Seite (RHS) ist der eigentliche Konstruktor einer Klasse. Die grundlegende Definition lautet:

Prüft das aktuelle Objekt und gibt true zurück, wenn das Objekt vom angegebenen Objekttyp ist.

Hier sind einige gute Beispiele und hier ist ein Beispiel, das direkt aus Mozillas Entwickler-Website :

var color1 = new String("green");
color1 instanceof String; // returns true
var color2 = "coral"; //no type specified
color2 instanceof String; // returns false (color2 is not a String object)

Erwähnenswert ist auch instanceof wird als wahr ausgewertet, wenn das Objekt vom Prototyp der Klasse erbt:

var p = new Person("Jon");
p instanceof Person

Das heißt p instanceof Person wahr ist, da p erbt von Person.prototype .

Gemäß der Anfrage des Auftraggebers

Ich habe ein kleines Beispiel mit einem Beispielcode und einer Erklärung hinzugefügt.

Wenn Sie eine Variable deklarieren, geben Sie ihr einen bestimmten Typ.

Zum Beispiel:

int i;
float f;
Customer c;

Die obigen Angaben zeigen Ihnen einige Variablen, nämlich i , f y c . Die Typen sind integer , float und eine benutzerdefinierte Customer Datentyp. Typen wie die oben genannten könnten für jede Sprache sein, nicht nur für JavaScript. Wenn Sie in JavaScript eine Variable deklarieren, legen Sie jedoch nicht ausdrücklich einen Typ fest, var x x kann eine Zahl / eine Zeichenkette / ein benutzerdefinierter Datentyp sein. Was also instanceof prüft das Objekt, um zu sehen, ob es von dem Typ ist, der oben angegeben wurde, indem es die Customer Objekt, das wir tun könnten:

var c = new Customer();
c instanceof Customer; //Returns true as c is just a customer
c instanceof String; //Returns false as c is not a string, it's a customer silly!

Oben haben wir gesehen, dass c wurde mit dem Typ Customer . Wir haben sie neu erstellt und überprüft, ob sie vom Typ Customer oder nicht. Sicher ist, es gibt true zurück. Dann noch mit der Customer Objekt prüfen wir, ob es sich um ein String . Nein, definitiv kein String wir haben eine Customer Objekt nicht ein String Objekt. In diesem Fall gibt sie false zurück.

Es ist wirklich so einfach!

97voto

webnesto Punkte 1319

Es gibt eine wichtige Facette von instanceof, die in den bisherigen Kommentaren nicht angesprochen wurde: Vererbung. Eine Variable, die mit instanceof ausgewertet wird, könnte aufgrund der prototypischen Vererbung für mehrere "Typen" true zurückgeben.

Definieren wir zum Beispiel einen Typ und einen Subtyp:

function Foo(){ //a Foo constructor
    //assign some props
    return this;
}

function SubFoo(){ //a SubFoo constructor
    Foo.call( this ); //inherit static props
    //assign some new props
    return this;
}

SubFoo.prototype = Object.create(Foo.prototype); // Inherit prototype
SubFoo.prototype.constructor = SubFoo;

Da wir nun einige "Klassen" haben, können wir einige Instanzen erstellen und herausfinden, wovon sie Instanzen sind:

var 
    foo = new Foo()
,   subfoo = new SubFoo()
;

alert( 
    "Q: Is foo an instance of Foo? "
+   "A: " + ( foo instanceof Foo ) 
); // -> true

alert( 
    "Q: Is foo an instance of SubFoo? " 
+   "A: " + ( foo instanceof SubFoo ) 
); // -> false

alert( 
    "Q: Is subfoo an instance of Foo? "
+   "A: " + ( subfoo instanceof Foo ) 
); // -> true

alert( 
    "Q: Is subfoo an instance of SubFoo? "
+   "A: " + ( subfoo instanceof SubFoo ) 
); // -> true

alert( 
    "Q: Is subfoo an instance of Object? "
+   "A: " + ( subfoo instanceof Object ) 
); // -> true

Sehen Sie diese letzte Zeile? Alle "new"-Aufrufe einer Funktion geben ein Objekt zurück, das von Object erbt. Dies gilt selbst dann, wenn die Kurzschrift für die Objekterstellung verwendet wird:

alert( 
    "Q: Is {} an instance of Object? "
+   "A: " + ( {} instanceof Object ) 
); // -> true

Und was ist mit den "Klassendefinitionen" selbst? Was sind sie für Instanzen?

alert( 
    "Q: Is Foo an instance of Object? "
+   "A:" + ( Foo instanceof Object) 
); // -> true

alert( 
    "Q: Is Foo an instance of Function? "
+   "A:" + ( Foo instanceof Function) 
); // -> true

Ich denke, dass es wichtig ist, zu verstehen, dass jedes Objekt eine Instanz von MEHREREN Typen sein kann, da man (fälschlicherweise) annehmen könnte, dass man zwischen, sagen wir, einem Objekt und einer Funktion unterscheiden kann, indem man instanceof . Wie dieses letzte Beispiel deutlich zeigt, ist eine Funktion es ein Objekt.

Dies ist auch wichtig, wenn Sie Vererbungsmuster verwenden und die Nachkommenschaft eines Objekts mit anderen Methoden als dem Duck-Typing bestätigen wollen.

Ich hoffe, das hilft allen, die auf der Suche sind. instanceof .

90voto

Jay Conrod Punkte 27696

Die anderen Antworten hier sind richtig, aber sie gehen nicht darauf ein, wie instanceof tatsächlich funktioniert, was für einige Sprachjuristen von Interesse sein könnte.

Jedes Objekt in JavaScript hat einen Prototyp, der über die __proto__ Eigentum. Funktionen haben auch eine prototype Eigenschaft, die die anfängliche __proto__ für alle von ihnen erstellten Objekte. Wenn eine Funktion erstellt wird, erhält sie ein eindeutiges Objekt für prototype . Die instanceof Operator nutzt diese Einzigartigkeit, um Ihnen eine Antwort zu geben. So sieht es aus instanceof aussehen könnte, wenn Sie es als Funktion schreiben würden.

function instance_of(V, F) {
  var O = F.prototype;
  V = V.__proto__;
  while (true) {
    if (V === null)
      return false;
    if (O === V)
      return true;
    V = V.__proto__;
  }
}

Dies ist im Grunde eine Paraphrase von ECMA-262 Ausgabe 5.1 (auch bekannt als ES5), Abschnitt 15.3.5.3.

Beachten Sie, dass Sie jedes beliebige Objekt einer Funktion zuweisen können. prototype Eigenschaft, und Sie können einem Objekt die __proto__ nachdem sie konstruiert wurde. Dies wird Ihnen einige interessante Ergebnisse liefern:

function F() { }
function G() { }
var p = {};
F.prototype = p;
G.prototype = p;
var f = new F();
var g = new G();

f instanceof F;   // returns true
f instanceof G;   // returns true
g instanceof F;   // returns true
g instanceof G;   // returns true

F.prototype = {};
f instanceof F;   // returns false
g.__proto__ = {};
g instanceof G;   // returns false

47voto

Stephen Belanger Punkte 5901

Ich denke, es ist erwähnenswert, dass instanceof durch die Verwendung des Schlüsselworts "new" bei der Deklaration des Objekts definiert ist. In dem Beispiel von JonH;

var color1 = new String("green");
color1 instanceof String; // returns true
var color2 = "coral";
color2 instanceof String; // returns false (color2 is not a String object)

Was er nicht erwähnt hat, ist dies;

var color1 = String("green");
color1 instanceof String; // returns false

Durch die Angabe von "new" wurde der Endzustand der String-Konstruktorfunktion tatsächlich in die Variable color1 kopiert, anstatt ihn einfach auf den Rückgabewert zu setzen. Ich denke, dies zeigt besser, was das Schlüsselwort new bewirkt;

function Test(name){
    this.test = function(){
        return 'This will only work through the "new" keyword.';
    }
    return name;
}

var test = new Test('test');
test.test(); // returns 'This will only work through the "new" keyword.'
test // returns the instance object of the Test() function.

var test = Test('test');
test.test(); // throws TypeError: Object #<Test> has no method 'test'
test // returns 'test'

Bei Verwendung von "new" wird der Wert von "this" innerhalb der Funktion der deklarierten var zugewiesen, während bei Nichtverwendung stattdessen der Rückgabewert zugewiesen wird.

8voto

Tarek Saied Punkte 6382

Und Sie können es zur Fehlerbehandlung und Fehlersuche verwenden, etwa so:

try{
    somefunction();
} 
catch(error){
    if (error instanceof TypeError) {
        // Handle type Error
    } else if (error instanceof ReferenceError) {
        // Handle ReferenceError
    } else {
        // Handle all other error types
    }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X