3

Is there any difference between following pieces of code:

inst instanceof Constr

and

inst.__proto__ === Constr.prototype

for example:

var xyz = {}
xyz instanceof Object

and

xyz.__proto__ === Object.prototype

? If so, what is the difference, which one is the preferred?

ducin
  • 25,621
  • 41
  • 157
  • 256

4 Answers4

4

__proto__ isn't part of the ECMAScript 5 specification, and you have no guarantee of future support. The standard ways to access the prototype of an object are to access the prototype of the constructor or, better, Object.getPrototypeOf (but this doesn't work on IE8).

instanceof checks the prototype of the constructor but also "tests presence of constructor.prototype in object prototype chain.".

If your goal is to check if an object is an instance of a specific class, and it's OK for you if it's not a direct instance, then you should use the instanceof operator : it's really just made for that.

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
2

There are two differences. As others have mentioned before instanceof is recursive. You can implement your own version of instanceof as follows:

function instanceOf(obj, func) {
    return Object.isPrototypeOf.call(func.prototype, obj);
}

This function depends upon the availability of the Object.prototype.isPrototypeOf function.

The second difference is only for browsers. As mentioned in the following answer the actual implementation of instanceof is as follows in browsers:

function instanceOf(obj, func) {
    var prototype = func.prototype;

    while (obj = Object.getPrototypeOf(obj)) { //traverse the prototype chain
        if (typeof object === "xml")           //workaround for XML objects
            return prototype === XML.prototype;
        if (obj === prototype) return true;    //object is instanceof constructor
    }

    return false; //object is not instanceof constructor
}

That's all. For more information see the documentation of instanceof: https://developer.mozilla.org/en/JavaScript/Guide/Details_of_the_Object_Model#Determining_instance_relationships

Community
  • 1
  • 1
Aadit M Shah
  • 72,912
  • 30
  • 168
  • 299
  • By "actual implementation in browsers" you again mean abstract pseudo code that no actual implementation would use in actually implementing it :P – Esailija Jun 28 '13 at 13:19
  • @Esailija I wouldn't actually bother looking up the code for `instanceof` in the V8 engine now, would I? =P – Aadit M Shah Jun 28 '13 at 13:27
1

Instanceof checks further

var GrandParent=function(){};
var Parent = function(){}
Parent.prototype=new GrandParent()
var Child = function(){};
Child.prototype=new Parent()

var c=new Child();
console.log(c instanceof GrandParent);//true
console.log(c.__proto__ === GrandParent);//false
HMR
  • 37,593
  • 24
  • 91
  • 160
1

There actually is a third way, that looks a lot like the non-standard __proto__ examples:

Object.getPrototypeOf([]) === Array.prototype

Be weary:

console.log([] instanceof Object);//ture
console.log(Object.getPrototypeOf([]) === Object.prototype);//false

Basically, the instanceof operator checks the entire prototype-chain, the other methods don't

Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149