543 Stimmen

Was ist der Unterschied zwischen typeof und instanceof und wann sollte das eine im Gegensatz zum anderen verwendet werden?

In meinem speziellen Fall:

callback instanceof Function

または

typeof callback == "function"

Spielt das überhaupt eine Rolle, was ist der Unterschied?

Zusätzliche Ressource:

JavaScript-Garten typeof gegen instanceof

716voto

Szymon Wygnański Punkte 9996

使用方法 instanceof für benutzerdefinierte Typen:

var ClassFirst = function () {};
var ClassSecond = function () {};
var instance = new ClassFirst();
typeof instance; // object
typeof instance == 'ClassFirst'; // false
instance instanceof Object; // true
instance instanceof ClassFirst; // true
instance instanceof ClassSecond; // false 

使用方法 typeof für einfache eingebaute Typen:

'example string' instanceof String; // false
typeof 'example string' == 'string'; // true

'example string' instanceof Object; // false
typeof 'example string' == 'object'; // false

true instanceof Boolean; // false
typeof true == 'boolean'; // true

99.99 instanceof Number; // false
typeof 99.99 == 'number'; // true

function() {} instanceof Function; // true
typeof function() {} == 'function'; // true

使用方法 instanceof für komplexe eingebaute Typen:

/regularexpression/ instanceof RegExp; // true
typeof /regularexpression/; // object

[] instanceof Array; // true
typeof []; //object

{} instanceof Object; // true
typeof {}; // object

Und der letzte Punkt ist ein bisschen schwierig:

typeof null; // object

125voto

Soviut Punkte 83233

Beide sind in ihrer Funktionalität ähnlich, da sie beide Typinformationen zurückgeben, ich persönlich bevorzuge jedoch instanceof weil es tatsächliche Typen und keine Zeichenketten vergleicht. Der Typvergleich ist weniger anfällig für menschliche Fehler, und er ist technisch gesehen schneller, da er Zeiger im Speicher vergleicht, anstatt ganze Zeichenketten zu vergleichen.

114voto

Kenneth J Punkte 4710

Ein guter Grund, typeof zu verwenden, ist, wenn die Variable undefiniert sein kann.

alert(typeof undefinedVariable); // alerts the string "undefined"
alert(undefinedVariable instanceof Object); // throws an exception

Ein guter Grund, instanceof zu verwenden, ist, wenn die Variable null sein kann.

var myNullVar = null;
alert(typeof myNullVar ); // alerts the string "object"
alert(myNullVar  instanceof Object); // alerts "false"

Meiner Meinung nach hängt es also wirklich davon ab, welche Art von Daten Sie überprüfen wollen.

55voto

Vladimir Liubimov Punkte 874

Um die Dinge klar zu machen, müssen Sie zwei Fakten kennen:

  1. Die instanceof Operator prüft, ob die Prototypeigenschaft eines Konstrukteur erscheint irgendwo in der Prototypenkette eines Objekts. In den meisten Fällen bedeutet dies, dass das Objekt erstellt durch Verwendung dieses Konstruktors oder eines seiner Abkömmlinge. Der Prototyp kann aber auch explizit gesetzt werden durch Object.setPrototypeOf() Methode (ECMAScript 2015) oder durch die __proto__ Eigenschaft (alte Browser, veraltet). Das Ändern des Prototyps eines Objekts wird jedoch aus Leistungsgründen nicht empfohlen.

Daher ist instanceof nur auf Objekte anwendbar. In den meisten Fällen werden Sie keine Konstruktoren verwenden, um Zeichenketten oder Zahlen zu erstellen. Das können Sie. Aber man tut es fast nie.

Auch instanceof kann nicht überprüfen, welcher Konstruktor genau verwendet wurde, um das Objekt zu erstellen, sondern gibt true zurück, auch wenn das Objekt von der zu überprüfenden Klasse abgeleitet ist. In den meisten Fällen ist dies das gewünschte Verhalten, aber manchmal ist es nicht so. Das müssen Sie also im Hinterkopf behalten.

Ein weiteres Problem ist, dass verschiedene Bereiche unterschiedliche Ausführungsumgebungen haben. Das bedeutet, dass sie unterschiedliche Built-Ins haben (unterschiedliche globale Objekte, unterschiedliche Konstruktoren usw.). Dies kann zu unerwarteten Ergebnissen führen.

Zum Beispiel, [] instanceof window.frames[0].Array wird zurückgegeben false denn Array.prototype !== window.frames[0].Array und Arrays erben von ersterem.
Außerdem kann er nicht für undefinierte Werte verwendet werden, da er keinen Prototyp hat.

  1. Die typeof Operator prüft, ob der Wert zu einer von sechs Grundtypen : " Nummer ", " String ", " boolean ", " Objekt ", " Funktion " oder " undefiniert ". Zur Zeichenkette "object" gehören alle Objekte (außer Funktionen, die Objekte sind, aber einen eigenen Wert im typeof-Operator haben), und auch "null"-Werte und Arrays (für "null" gibt es einen Fehler, aber dieser Fehler ist so alt, dass er zum Standard geworden ist). Es ist nicht auf Konstruktoren angewiesen und kann auch verwendet werden, wenn der Wert undefiniert ist. Aber es gibt keine Details über Objekte. Wenn Sie es also brauchen, gehen Sie zu instanceof.

Lassen Sie uns nun über eine heikle Sache sprechen. Was passiert, wenn Sie einen Konstruktor verwenden, um einen primitiven Typ zu erstellen?

let num = new Number(5);
console.log(num instanceof Number); // print true
console.log(typeof num); // print object
num++; //num is object right now but still can be handled as number
//and after that:
console.log(num instanceof Number); // print false
console.log(typeof num); // print number

Scheint wie Magie. Ist es aber nicht. Es handelt sich um sogenanntes Boxing (Einpacken eines primitiven Wertes in ein Objekt) und Unboxing (Herausnehmen des eingepackten primitiven Wertes aus dem Objekt). Diese Art von Code scheint "ein bisschen" anfällig zu sein. Natürlich kann man es vermeiden, primitive Typen mit Konstruktoren zu erzeugen. Aber es gibt noch eine andere mögliche Situation, in der Boxing Sie treffen kann. Wenn Sie Function.call() oder Function.apply() auf einen primitiven Typ anwenden.

function test(){
  console.log(typeof this);
} 
test.apply(5);

Um dies zu vermeiden, können Sie den Strict-Modus verwenden:

function test(){
  'use strict';
  console.log(typeof this);
} 
test.apply(5);

Update: Seit ECMAScript 2015 gibt es einen weiteren Typ namens Symbol, der seinen eigenen typeof == hat. "Symbol" .

console.log(typeof Symbol());
// expected output: "symbol"

Sie können darüber auf MDN lesen: ( Symbol , typeof ).

18voto

Justin Force Punkte 5907

Ich habe ein wirklich interessantes (sprich "schreckliches") Verhalten in Safari 5 und Internet Explorer 9 entdeckt. Ich habe dies mit großem Erfolg in Chrome und Firefox verwendet.

if (typeof this === 'string') {
    doStuffWith(this);
}

Dann teste ich im IE9, und es funktioniert überhaupt nicht. Große Überraschung. Aber in Safari funktioniert es nur sporadisch! Also beginne ich mit der Fehlersuche und stelle fest, dass der Internet Explorer immer zurückkehrend false . Aber das Seltsamste ist, dass Safari scheint eine Art von Optimierung in seiner JavaScript-VM zu tun, wo es ist true die erste Zeit, aber false jedes Mal, wenn Sie auf Nachladen drücken!

Mein Gehirn ist fast explodiert.

Also habe ich mich jetzt für das hier entschieden:

if (this instanceof String || typeof this === 'string')
    doStuffWith(this.toString());
}

Und jetzt funktioniert alles wunderbar. Beachten Sie, dass Sie "a string".toString() und gibt nur eine Kopie der Zeichenkette zurück, d. h.

"a string".toString() === new String("a string").toString(); // true

Ich werde also von nun an beides verwenden.

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