2013-12-12 16 views
5

In Stoyan Stefanov's book Object-Oriented javascript, a pagina 103 ha il seguente. Tuttavia, quando provo questo, ottengo un risultato diverso con h instanceof Object. Mi manca qualcosa, ho cambiato qualcosa in JS o è un errore nel libro.instanceof - incoerenza javascript in javascript Object-Oriented di 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

Dove hai provato? – PSL

+0

Riga di comando di Google Chrome. – KingKongFrog

+0

Deve essere "true" solo. Dove l'hai preso come "falso"? – PSL

risposta

3

Se questo è quello che dice il libro, poi il libro non è corretto. (E cercare il contenuto del libro in Amazon.com conferma l'errore.)

Il risultato true che si ottiene in Google Chrome è il risultato corretto.

Mentre l'oggetto h eredita dal .prototype sulla funzione Hero, che .prototype eredita dalla .prototype sulla funzione Object. Ciò significa che h eredita entrambi da Hero.prototype e Object.prototype ed è considerato un'istanza di entrambi i costruttori.

L'unico modo in cui non lo sarebbe se Hero.prototype fosse un oggetto che non ereditava da Object.prototype. Ma in quell'esempio usa l'oggetto predefinito, quindi eredita.

0

Utilizzando l'operatore instanceof non si verifica se qualcosa è stato creato da un determinato costruttore, ma se qualcosa eredita da un determinato oggetto (se un determinato oggetto si trova nella catena di un prototipo di qualcosa). foo instanceof F ha esattamente lo stesso risultato di un ricorsiva * 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 

Con questo in mente, è abbastanza evidente che se non si cambia il prototipo di una funzione per un oggetto che non eredita da Object.prototype, tutte le istanze create con quella funzione come costruttore erediteranno da Object.prototype, quindi saranno istanze di Object.

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

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

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

instanceof spessore (soli scopi teorici, non v'è alcuna utilità pratica per esso):

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