chacham15
chacham15

Reputation: 14251

How can I check instanceof without the proto chain in javascript?

How can I check instanceof without the proto chain in javascript?

var EventEmitter = require('events').EventEmitter;

var Foo = function(){

};
Foo.prototype = EventEmitter.prototype;

var Bar = function(){

};
Bar.prototype = EventEmitter.prototype;

var f = new Foo();
var b = new Bar();

f instanceof Foo; //returns true
b instanceof Bar; //returns true

f instanceof Bar; //returns true
b instanceof Foo; //returns true

Essentially, I want those last two lines to return false. How do I do that?

Upvotes: 2

Views: 189

Answers (1)

thefourtheye
thefourtheye

Reputation: 239443

When you do an instanceof check,

f instanceof Foo

it will take the internal [[prototype]] object (which can be accessed with Object.getPrototypeOf) and find if it occurs anywhere in the Foo's prototype chain, till it finds Object along the line.

Another important point to be noted here is, Foo.prototype is the same as Bar.prototype. Because you assign the same object to both the properties. You can confirm this like this

console.log(Foo.prototype === Bar.prototype);
// true
console.log(Object.getPrototypeOf(f) === Object.getPrototypeOf(b));
// true

That is why all the instanceof checks you made in the question return true.

To fix this, you need to create the prototype Objects, based on EventEmitter's prototype (not with it). You can use Object.create to do that for you. It takes an object, which should be used as the prototype of the newly constructed object.

Foo.prototype = Object.create(EventEmitter.prototype);
...
Bar.prototype = Object.create(EventEmitter.prototype);

with this change,

console.log(Foo.prototype === Bar.prototype);
// false
console.log(Object.getPrototypeOf(f) === Object.getPrototypeOf(b));
// false
console.log(f instanceof Foo);
// true
console.log(b instanceof Bar);
// true
console.log(f instanceof Bar);
// false
console.log(b instanceof Foo);
// false

Upvotes: 2

Related Questions