b Tech
b Tech

Reputation: 452

Why does an object's constructor property changes if constructor's prototype is changed?

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

Answers (2)

shiponcs
shiponcs

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

Max Koretskyi
Max Koretskyi

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

Related Questions