带有共享原型的instanceof

时间:2014-07-13 09:23:23

标签: javascript prototype instanceof

以下代码记录'true'4次:

var menuItem = {
    name: "New menuItem",
};

function food(name) {
    if(name) this.name = name;
    //this.resourceType = "food";
}
food.prototype = menuItem;

function drink(name) {
    if(name) this.name = name;
    //this.resourceType = "drink";
}
drink.prototype = menuItem;

var burger = new food();
var coke = new drink();

console.log(buger instanceof food);
console.log(burger instanceof drink);
console.log(coke instanceof food);
console.log(coke instanceof drink);

但是,如果我注释掉以下两行:

//food.prototype = menuItem;
//drink.prototype = menuItem;

然后代码执行我想要的操作并记录为“buger instanceof food”和“coke instanceof drink”。

当它们共享相同的原型(menuItem)时,有没有办法检查menuItem是正确的食物或饮料的实例?

我不想像这样存储类型:

this.resourceType = "food";

如果有更好的方法。

1 个答案:

答案 0 :(得分:2)

对于每个构造函数,创建一个新对象以用作该构造函数的prototype,并让每个新的原型对象使用menuItem作为原型:

food.prototype = Object.create(menuItem);

因此,food实例和drink实例的原型链现在看起来像:

[food instance] > [food prototype] > [menuItem]
[drink instance] > [drink prototype] > [menuItem]

旧链看起来像:

[food instance] > [menuItem]
[drink instance] > [menuItem]

正如您所看到的,在旧链中,food实例和drink实例实际上具有相同的原型父级,因此food构造的对象和drink构造对象具有相同的原型父对象。在新系统下,fooddrink具有单独的原型父级。

MDN对instanceof

有很好的描述
  

instanceof运算符测试对象在其原型链中是否具有构造函数的prototype属性。

因此,当您在burger instanceof drink &#34的原型链中测试drink.prototype时,您正在测试" burger ;。以前,drink.prototype等于menuItem,因此您确实在menuItem的原型链中测试" burger& #34 ;.现在,drink.prototype是其自己的唯一值,与food.prototype分开,因此结果为false