instanceof - javascript inconsistency in Object-Oriented javascript by Stoyan Stefanov

StackOverflow https://stackoverflow.com/questions/20553358

  •  01-09-2022
  •  | 
  •  

Question

In Stoyan Stefanov's book Object-Oriented javascript, on page 103 he has the following. However when I try this, I get a different result with h instanceof Object. Am I missing something, has something in JS changed since or is this an error in the book.

>>> 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

Était-ce utile?

La solution

If that's what the book says, then the book is incorrect. (And searching the book content in Amazon.com confirms the error.)

Your true result that you get in Google Chrome is the correct result.

While the h object inherits from the .prototype on the Hero function, that .prototype inherits from the .prototype on the Object function. This means that h inherits both from Hero.prototype and Object.prototype, and is considered an instance of both constructors.

The only way it wouldn't be would be if Hero.prototype was an object that did not inherit from Object.prototype. But in that example, it uses the default object, so it does indeed inherit.

Autres conseils

Using the instanceof operator you don't test whether something was created by a certain constructor, but whether something inherits from a certain object (whether a certain object is in the prototype chain of something). foo instanceof F has exactly the same result as a recursive* 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

With that in mind, it is pretty obvious that if you don't change the prototype of a function to an object which doesn't inherit from Object.prototype, all the instances constructed with that function as constructor will inherit from Object.prototype, so they will be instances of Object.

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

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

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

instanceof shim (just theoretical purposes, there is no practical use for it):

function instanceOf(object, constructor) {
  if (!object) return false;
  var object = Object.getPrototypeOf(object);
  if (object === constructor.prototype) return true;
  return instanceOf(object, constructor);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top