41

Suppose we have the following:

function Super() {
      // init code
}

function Sub() {
      Super.call(this);
      // other init code
}

Sub.prototype = new Super();

var sub = new Sub();

Then, in some other part of our ocde, we can use either of the following to check for the relationship:

sub instanceof Super;   

or

Super.prototype.isPrototypeOf( sub )

Either way, we need to have both the object (sub), and the parent constructor (Super). So, is there any reason why you'd use one vs the other? Is there some other situation where the distinction is more clear?

I've already carefully read 2464426, but didn't find a specific enough answer.

Community
  • 1
  • 1
user1689498
  • 413
  • 1
  • 4
  • 5
  • possible duplicate of [Why do we need the isPrototypeOf at all?](http://stackoverflow.com/questions/5972991/why-do-we-need-the-isprototypeof-at-all) – plalx Aug 20 '13 at 19:54
  • Based on the OP's comment, I'd say this question is closer to "Why do we need `instanceof` at all?" but I agree that it's probably close enough. – apsillers Aug 20 '13 at 20:22
  • Possible duplicate of [What's the difference between isPrototypeOf and instanceof in Javascript?](https://stackoverflow.com/questions/2464426/whats-the-difference-between-isprototypeof-and-instanceof-in-javascript) – Oliver Sieweke Feb 23 '19 at 22:34

5 Answers5

45

Imagine you don't use constructors in your code, but instead use Object.create to generate objects with a particular prototype. Your program might be architected to use no constructors at all:

var superProto = {
    // some super properties
}

var subProto = Object.create(superProto);
subProto.someProp = 5;

var sub = Object.create(subProto);

console.log(superProto.isPrototypeOf(sub));  // true
console.log(sub instanceof superProto);      // TypeError

Here, you don't have a constructor function to use with instanceof. You can only use subProto.isPrototypeOf(sub).

raaj
  • 13
  • 1
  • 5
apsillers
  • 112,806
  • 17
  • 235
  • 239
  • 2
    Thanks for the answer, and I have one quick follow up: Why do we need instanceof, since isPrototypeOf would seem to work in all cases? Is it historical or are there performance advantages, or something else? – user1689498 Aug 20 '13 at 19:48
  • @user1689498 Simply because `isPrototypeOf` has been implemented later. – plalx Aug 20 '13 at 19:51
  • 3
    @user1689498: `instanceof` is older, I believe, and looks similar to Java, which was a big deal when JavaScript was first introduced. It also is a little cleaner. But yes, `isPrototypeOf` is the more generally useful one. – Scott Sauyet Aug 20 '13 at 19:52
14

It makes little difference when you use constructor functions. instanceof is a little cleaner, perhaps. But when you don't...:

var human = {mortal: true}
var socrates = Object.create(human);
human.isPrototypeOf(socrates); //=> true
socrates instanceof human; //=> ERROR!

So isPrototypeOf is more general.

Scott Sauyet
  • 49,207
  • 4
  • 49
  • 103
  • 1
    Great! :) But one thing. «human» in this example should be a «Human». I mean it should be a class (All people), not a single instance (a human). – Naeel Maqsudov Jun 04 '14 at 04:37
  • @NaeelMaqsudov: Beware analogies between languages. Javascript has no classes. Even in when the travesty of `class` syntactic sugar is added in ES6, the language will still not have something really like, say, Java classes. Prototypal inheritance has some parallels with classical inheritance, but the analogies are rough ones. In any way of doing inheritance, there will be an object such as this --- perhaps the prototype of a constructor function. But note: `var naeel = Object.create(human); naeel instanceof human; //=> true`. This strips away some of the sugar of constructor functions. – Scott Sauyet Jun 04 '14 at 13:00
  • Sorry, bad cut-and-paste error. `naeel instanceof human; //=> ERROR.` But `human.prototypOf(naeel); //=> true`. – Scott Sauyet Jun 04 '14 at 14:20
  • Wow. I think I need some caffeine. `isPrototypeOf`. – Scott Sauyet Jun 04 '14 at 17:20
  • 1
    @NaeelMaqsudov: Most importantly, note that although historically constructor functions predated `Object.create`, it's the latter which is the more fundamental construct. The constructor function could be easily built on top of `Object.create`, which is the fundamental behavior, and `instanceOf` could be built on top of `isPrototypeOf`, but the reverse of these are not true, or at least have no obvious solutions. Using this mechanism, you can just as easily claim that all such constructed object are 'human' objects as you can with the constructor function. – Scott Sauyet Jun 04 '14 at 20:47
1

According to this MDN Ref:

isPrototypeOf() differs from the instanceof operator. In the expression object instanceof AFunction, the object prototype chain is checked against AFunction.prototype, not against AFunction itself.

S.Serpooshan
  • 7,608
  • 4
  • 33
  • 61
0
var neuesArray = Object.create(Array);

Array.isPrototypeOf(neuesArray);            // true
neuesArray instanceof Array                 // false
neuesArray instanceof Object                // true
Array.isArray(neuesArray);                  // false
Array.prototype.isPrototypeOf(neuesArray);  // false
Object.prototype.isPrototypeOf(neuesArray); // true

Do you understand my friend :) - is simple

ozanmuyes
  • 721
  • 12
  • 26
svenskanda
  • 19
  • 1
0

Just complement @apsillers's answer

object instanceof constructor

var superProto = {}

// subProto.__proto__.__proto__ === superProto
var subProto = Object.create(superProto);
subProto.someProp = 5;
// sub.__proto__.__proto__ === subProto
var sub = Object.create(subProto);

console.log(superProto.isPrototypeOf(sub)); // true
console.log(sub instanceof superProto); // TypeError: Right-hand side of 'instanceof' is not callable

// helper utility to see if `o1` is
// related to (delegates to) `o2`
function isRelatedTo(o1, o2) {
  function F(){}
  F.prototype = o2;
  // ensure the right-hand side of 'instanceof' is callable
  return o1 instanceof F; 
}
isRelatedTo( b, a ); 

TypeError: Right-hand side of 'instanceof' is not callable

instanceof need the right-hand value to be callable, which means it must be a function(MDN call it as the constructor)

and instanceof tests the presence of constructor.prototype in object's prototype chain.

but isPrototypeOf() don't have such limit. While instanceof checks superProto.prototype, isPrototypeOf() checks superProto directly.

Tina Chen
  • 2,010
  • 5
  • 41
  • 73