Reputation: 53
What I'm attempting to do is create a simple object hierarchy in Javascript where each object in the hierarchy has it's own set of properties, while at the same time be able to use instanceof on those newly created objects. In other words, I wanted my base object (see Person below) to actually contain the firstName and lastName properties. I didn't ultimately want all of my properties to be mashed onto the same "this". I want a nice/neat true Object hierarchy.
To do this, I thought this was the right approach, but it looks like I'm wrong:
var Person = function (firstName, lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
var Ninja = function (beltColor)
{
this.beltColor = beltColor;
}
Ninja.prototype = new Person ("George", "Clooney");
var ninja1 = new Ninja ("Black");
Ninja.prototype = new Person ("Scarlett", "Johansson");
var ninja2 = new Ninja ("Blue");
Ninja.prototype = new Person ("Brad", "Pitt");
var ninja3 = new Ninja ("Green");
console.log (ninja1 instanceof Ninja); // false
console.log (ninja1 instanceof Person); // true
console.log (ninja2 instanceof Ninja); // false
console.log (ninja2 instanceof Person); // true
console.log (ninja3 instanceof Ninja); // true
console.log (ninja3 instanceof Person); // true
The above code (in my mind) would effectivly create three main objects using the Ninja constructor and the resultant ninja1.__proto__, ninja2.__proto__ and ninja3.__proto__
objects would contain the firstName/lastName properties (which is what I want). These __proto__ objects would also be of "type" Person, being that they were created with the Person constructor and the ninja1, ninja2 and ninja3 objects would be of type "Ninja" (or so I thought), because they were created with the Ninja constructor.
I realize that the reassignment of the Ninja.prototype to a newly created object via the Person constructor is what is throwing of the instanceof
operator, but for the life of me, I don't know why.
So I have two questions:
1) Why does the reassignment of the Ninja.prototype to a newly created object via the Person constructor throw off the instanceof
operator?
2) What is the correct approach to do what I'm attempting to do? In other words, create a simple object hiearchy where the properties are truly at different levels of the hierarchy, while also being able to use instanceof
in a way that makes sense?
Upvotes: 1
Views: 441
Reputation: 2123
The instanceOf
method here does not give the constructor of the Ninja object because you have manually assigned the prototype for the NInja object as the "Person" so when traversing through the prototype chain it will have Person object. If you are expecting what you want you can try the below code
var Person = function (firstName, lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
var Ninja = function (firstName, lastName, beltcolor)
{
this.beltColor = beltColor;
Person.apply(this,arguments);
}
var ninja1 = new Ninja ( "George", "Clooney", "Black");
var ninja2 = new Ninja ("Scarlett", "Johansson","Blue");
var ninja3 = new Ninja ("Brad", "Pitt", "Green");
console.log (ninja1 instanceof Ninja); // true
console.log (ninja1 instanceof Person); // false
console.log (ninja2 instanceof Ninja); // true
console.log (ninja2 instanceof Person); // false
console.log (ninja3 instanceof Ninja); // true
console.log (ninja3 instanceof Person); // false
console.log(ninja1.firstName); //George
Hope this helps you.
You can also look in to below link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain
Upvotes: 1
Reputation: 16020
Q1: Why does the reassignment of the Ninja.prototype to a newly created object via the Person constructor throw off the instanceof
operator?
This does so because the instanceof
operator works by going up the prototype chain and checking whether the internal actual prototype of the object ([[Prototype]]
) compares with the current prototype property of the constructor function.
Q2: What is the correct approach to do what I'm attempting to do? In other words, create a simple object hierarchy where the properties are truly at different levels of the hierarchy, while also being able to use instanceof
in a way that makes sense?
Prototypes are meant for items that are common to all instances of a constructor (for example all people have a brain, but not everyone has the same name). Instead of changing the prototype, add the first name and last name arguments directly as properties of instances of the Ninja
function, and make the prototype property of Ninja
a blank Person
(to cover the case of a person without a name and so that instanceof
returns true):
var Person = function (firstName, lastName)
{ this.firstName = firstName;
this.lastName = lastName;
}
var Ninja = function (beltColor, firstName, lastName)
{ this.beltColor = beltColor;
Person.call(this, firstName, lastName); // call parent function
}
Ninja.prototype = new Person("", ""); // do this so that instanceof returns true
var ninja1 = new Ninja ("Black", "George", "Clooney");
var ninja2 = new Ninja ("Blue", "Scarlett", "Johansson");
var ninja3 = new Ninja ("Green", "Brad", "Pitt");
console.log (ninja1 instanceof Ninja); // true
console.log (ninja1 instanceof Person); // true
console.log (ninja2 instanceof Ninja); // true
console.log (ninja2 instanceof Person); // true
console.log (ninja3 instanceof Ninja); // true
console.log (ninja3 instanceof Person); // true
Upvotes: 1
Reputation: 413717
The instanceof
operator looks at the cached prototype chain on the instance and compares it with the constructor you give it. If you've changed the prototype on the constructor, they no longer match.
If you don't change the prototype object completely, and just update properties, that won't happen.
Your object model seems odd; why wouldn't the names be instance properties, just like "belt color"?
Upvotes: 0