0

The following code logs 'true' 4 times:

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);

However if I comment out the following two lines:

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

Then the code does what I want and logs true for "buger instanceof food" and "coke instanceof drink".

Is there a way of checking if the menuItem is an instance of either food or drink correctly while they both share the same prototype (menuItem)?

I'd prefer not to have to store the type like so:

this.resourceType = "food";

If there is a better way of doing it.

1
  • You have some typos related to burger/buger.
    – RobG
    Commented Jul 13, 2014 at 9:46

1 Answer 1

2

For each constructor, create a new object to use as the prototype of that constructor, and have each new prototype object use menuItem as its prototype:

food.prototype = Object.create(menuItem);

So the prototype chain for a food instance and drink instance now looks like:

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

The old chain looked like:

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

As you can see, in the old chain, a food instance and drink instance really had the same prototype parent, so a food-constructed object and drink-constructed object has the same prototype parent. Under the new system, food and drink have separate prototype parents.

MDN has a good description of instanceof:

The instanceof operator tests whether an object has in its prototype chain the prototype property of a constructor.

So, when you test burger instanceof drink you're testing "is drink.prototype in the prototype chain of burger?". Previously, drink.prototype was equal to menuItem, so you were really testing "is menuItem in the prototype chain of burger?". Now, drink.prototype is its own unique value, separate from food.prototype, so the result is false.

2
  • Could you show me how the old prototype chain looked, please?
    – Jimmay
    Commented Jul 13, 2014 at 9:30
  • @Jimmay Added more explanation.
    – apsillers
    Commented Jul 13, 2014 at 9:43

Not the answer you're looking for? Browse other questions tagged or ask your own question.