2013-12-12 10 views
5

In Stoyan Stefanov's book Object-Oriented javascript, auf Seite 103 hat er Folgendes. Wenn ich dies jedoch versuche, bekomme ich ein anderes Ergebnis mit h instanceof Object. Fehle ich etwas, hat sich etwas in JS geändert oder ist das ein Fehler im Buch?instanceof - Javascript Inkonsistenz in Objektorientierte Javascript von Stoyan Stefanov

>>> function Hero(){} 
>>> var h = new Hero(); 
>>> var o = {}; 
>>> h instanceof Hero; 
true 
>>> h instanceof Object; 
false //true in Google Chrome 
>>> o instanceof Object; 
true 

Book excerpt

Google Chrome output

+1

Wo Sie es versucht? – PSL

+0

Google Chrome-Befehlszeile. – KingKongFrog

+0

Es muss nur "wahr" sein. Wo hast du es als "falsch" verstanden? – PSL

Antwort

3

Wenn das ist, was das Buch sagt, dann das Buch ist falsch. (Und das Durchsuchen des Buches Inhalt in Amazon.com bestätigt den Fehler.)

Ihr true Ergebnis, dass Sie in Google Chrome erhalten, ist das richtige Ergebnis.

Während das h Objekt erbt von den .prototype auf der Hero Funktion, die .prototype erbt von den .prototype auf der Object Funktion. Dies bedeutet, dass h sowohl von Hero.prototype als auch Object.prototype erbt und als eine Instanz beider Konstruktoren gilt.

Die einzige Möglichkeit wäre nicht, wenn Hero.prototype ein Objekt wäre, das nicht von Object.prototype erbte. In diesem Beispiel wird jedoch das Standardobjekt verwendet, sodass es tatsächlich erbt.

0

Mit dem Operator instanceof testen Sie nicht, ob etwas von einem bestimmten Konstruktor erstellt wurde, sondern ob etwas von einem bestimmten Objekt erbt (ob ein bestimmtes Objekt in der Prototypkette von etwas ist). foo Instanceof F hat genau das gleiche Ergebnis wie eine rekursive * Object.getPrototypeOf(foo) === F.prototype

var F = function() {}; 
var foo = new F(); 

foo instanceof F // true 
Object.getPrototypeOf(foo) === F.prototype // true 

F.prototype = {}; // changed the prototype of F 

foo instanceof F // false 
Object.getPrototypeOf(foo) === F.prototype // false 

foo instanceof Object // true 
Object.getPrototypeOf(Object.getPrototypeOf(foo)) === Object.prototype // true 

Vor diesem Hintergrund ist es ziemlich offensichtlich, dass, wenn Sie nicht den Prototyp einer Funktion auf ein Objekt ändern, die erbt nicht von Object.prototype, alle Instanzen, die mit dieser Funktion als Konstruktor erstellt werden, erben von Object.prototype und sind somit Instanzen von Object.

F.prototype = Object.create(null); 
var bar = new F(); 

bar instanceof F // true 
bar instanceof Object // false 

Referenz: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof

instanceof Shim (nur theoretische Zwecke, gibt es keine praktische Verwendung für sie):

function instanceOf(object, constructor) { 
    if (!object) return false; 
    var object = Object.getPrototypeOf(object); 
    if (object === constructor.prototype) return true; 
    return instanceOf(object, constructor); 
}