2015-03-07 3 views
2

Как я могу проверить instanceof без прото-цепи в javascript?Как я могу проверить instanceof без прото-цепочки в 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 

По сути, я хочу, чтобы эти последние две строки вернули значение false. Как мне это сделать?

ответ

2

Когда вы делаете instanceof чек,

f instanceof Foo 

потребуется внутренний [[prototype]] объект (к которому можно обратиться с Object.getPrototypeOf) и найти, если это происходит в любом месте в цепи прототипов Foo «s, пока он не найдет Object вдоль линии.

Еще один важный момент, который следует отметить здесь: Foo.prototype - это то же самое, что и Bar.prototype. Потому что вы назначаете один и тот же объект обоим свойствам. Вы можете подтвердить это, как этот

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

Вот почему все instanceof проверяет сделанные вами в вопросе возврата true.

Чтобы исправить это, вам необходимо создать прототип объектов на основе прототипа EventEmitter (не с ним). Вы можете использовать Object.create, чтобы сделать это за вас. Он принимает объект, который должен использоваться в качестве прототипа вновь построенного объекта.

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

с этим изменением,

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 
Смежные вопросы