2010-12-03 12 views
13

Dies ist wahrscheinlich eine dumme Frage, also bitte bleiben Sie bei mir.Verwendung von toString() anstelle von Konstruktor in JavaScript

Warum sehe ich so viele Beispiele, die testen, ob ein Objekt eine Funktion ist, indem ich toString() mit "[object Function]" vergleiche?

Zum Beispiel:

function isFunction(obj) { 
    return Object.prototype.toString.call(obj) == "[object Function]"; 
} 

Können wir nicht verwenden instanceof Function oder obj.constructor === Function? Sind diese nicht browserübergreifend kompatibel?

Diese scheint ineffizient, aber ist es? Warum?

+0

möglich Duplikat [jQuery isFunction und Internetexplorer] (http://stackoverflow.com/questions/3514336/jquerys-isfunction-and-internetexplorer) –

Antwort

7

Kurze Antwort ist, weil typeof /foo/ eine Funktion in Webkit-Browsern ist. CMS hat die lang gezogene Erklärung @jQuery's isFunction and InternetExplorer

Und instanceOf ist nicht zuverlässig, weil, wie Zuriy betont:

Die Probleme treten auf, wenn es in Multi-Frame-DOM-Umgebungen Scripting kommt. Kurz gesagt, Array-Objekte, die innerhalb eines Iframes erstellt wurden, teilen [[Prototyp]] 's nicht mit Arrays, die in einem anderen Iframe erstellt wurden. Ihre Konstrukteure sind verschiedene Objekte und so beide instanceof und Konstruktor überprüft fehlschlagen:

Große Artikel @http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/ von Zuriy zu dem Thema.

Beispiel aus dem Artikel entnommen:

var iframe = document.createElement('iframe'); 
document.body.appendChild(iframe); 
xArray = window.frames[window.frames.length-1].Array; 
var arr = new xArray(1,2,3); // [1,2,3] 

// Boom! 
arr instanceof Array; // false 

// Boom! 
arr.constructor === Array; // false 
+0

wann/warum ist instanceOf nicht zuverlässig? – Matt

+0

Ich kann sehen, warum "instanceOf" schlecht ist, aber was ist mit der Verwendung von "obj.constructor". Können wir ein Beispiel bekommen? –

+0

@meder danke! Ich hatte keine Ahnung. – Matt

1

Sie testen ihre toString-Methode nicht, sie rufen die toString-Methode des Objektprototyps unter obj auf, um sie in eine Zeichenfolge umzuwandeln. Eine Funktion wird als '[Objektfunktion]' in eine Zeichenfolge umgewandelt.

instanceof ist nicht zuverlässig und weder ist der Konstrukteur Weg. Der Konstruktor benötigt eine Überprüfung, um festzustellen, ob obj NULL ist oder nicht, bevor versucht wird, auf seine Konstruktoreigenschaft zuzugreifen - ich nehme auch an, dass es etwas langsamer ist als die Methode toString.

+0

Ich kann sehen, Warum "instanceof" ist nicht zuverlässig (Beispiel Funktion Array() {}), aber wo "Konstruktor" fehlschlagen würde? –

+1

@Eric aus genau dem gleichen Grund wie "instanceof" ein Problem ist: Die "Konstruktor" -Referenz würde für Objekte aus zwei verschiedenen Frames unterschiedlich sein, selbst wenn sie von der "gleichen" Funktion erstellt wurden, weil jede * Instanz * der Konstruktorfunktion (in jedem separaten Fenster) ist verschieden. – Pointy

Verwandte Themen