Reputation: 452
In the following code, taken from Helephant.com, If I set's a constructor's prototype Cat.prototype = new Pet()
to that of another object (of Pet
) then why does it modifies the constructor of it's object rufus.constructor
?
constructor
represents the function that created it. How can parent be modifiable the created it?
//PET CONSTRUCTOR
function Pet(name, species, hello)
{ this.name = name;
this.species = species;
this.hello = hello; }
//CAT CONSTRUCTOR
function Cat(name, hello, breed, whiskerLength)
{ this.name = name;
this.hello = hello;
this.breed = breed;
this.whiskerLength = whiskerLength;}
//SETTING CAT's PROTOTYPE to A NEW PET OBJECT.
Cat.prototype = new Pet();
//CREATING A NEW CAT OBJECT
var rufus= new Cat("rufus", "miaow", "Maine Coon", 7);
//CALLING CAT OBJ's CONSTRUCTOR PROPERTY
rufus.constructor;
//OUTPUT
function Pet(name, species, hello)
{
this.name = name;
this.species = species;
this.hello = hello; }
Is it a glitch by design. Can anyone explain this behavior. What benefits does it bring?
Upvotes: 1
Views: 187
Reputation: 1677
Maxim already answered it. Yet, if want to get Cat(...)
as the constructor of rufus
, you may like to append another line to your code-
Cat.prototype.constructor = Cat
Upvotes: 0
Reputation: 105439
When you type rufus.constructor
, JavaScript checks whether there is such property on rufus
object. It's not there, because you didn't create it there. Then it goes upwards through prototype chain and finds this property on rufus.__proto__.__proto__
which points at Pet
function and this function is outputted.
Here is more detailed explanation. When you declare a function:
function Pet() { /* ..code.. */ }
The interpreter creates the new function object from your declaration. Together with the function, it’s prototype
property is created and populated. This default value the prototype
is an object with property constructor
, which is set to the function itself. In our case, to Pet
:
Pet.prototype = { constructor: Pet}
This object becomes the .__proto__
of new Pet()
and is reachable from rufus
by rufus.__proto__.__proto__
. And this is exactly the object from which the constructor
property is read:
rufus.hasOwnProperty('constructor') // false;
Object.getPrototypeOf(rufus).hasOwnProperty('constructor') // false;
Object.getPrototypeOf(Object.getPrototypeOf(rufus)).hasOwnProperty('constructor') // true
This is exactly the reason why you'll see the creation of constructor
property on the child objects on many examples of inheritance in JavaScript:
Cat.prototype = Object.create(Pet.prototype); // it's better to use this instead of new Pet()
Cat.prototype.constructor = Pet;
Upvotes: 2