1

I am trying to understand why and when we use constructors in Javascript. I was wondering when and how we need to use the constructor of a child and when the parents. Based on my tests there is NO difference when I set the child constructor to itself or to the parent.Lets take a look at the below code :

function Mammal(name) {
    this.name = "###"+name;
}
    Cat.prototype = new Mammal();        // Here's where the inheritance occurs 
    Cat.prototype.constructor = Cat;       // Otherwise instances of Cat would have a    

function Cat(name) {
    this.name = name;
}

Now lets instantiate the Cat and Mamal class and see the name:

var mycat = new Cat('Felix');
Alert(mycat.name);         //OUTPUT : "Felix"

Now i want to set the constructor of Cat class to the Mamal. To do so I remove the below line

//Cat.prototype.constructor = Cat; -->Now the cat Constructor is set to its default(Mamal)

Now I expect that when I call mycat.name, it uses the Mamal constructor and alert "###Felix" BUT it doesn't. It shows exactly same as the previous result "Felix".

var mycat = new Cat('Felix');
Alert(mycat.name);         //Again OUTPUT is : "Felix" !! but I expected "###Felix"

So, why? And can you give me an example of a correct use of constructors in Javascript and when they are important?

1
  • 1
    Step 1 - get traceur. Step 2, use ES6 classes, if you really need to. Emulating classes in es5 is cumbersome, that's why they added all the sugar for you in es6. Commented Nov 24, 2014 at 2:50

1 Answer 1

2

Hopefully an examination of how this code runs should clear things up:

function Mammal(name) {
    this.name = "###" + name;
}
function Cat(name) {
    this.name = name;
}
Cat.prototype = new Mammal();
// omitted change of Cat.prototype.constructor

var felix = new Cat("Felix");
console.log(felix);

After defining the first two functions, we create a new Mammal, passing it a name of undefined, and putting the result into Cat.prototype. Now Cat.prototype is a Mammal with a name of ###undefined.

Then we create a new Cat, giving the Cat function a name of Felix. This Cat function sets its name property to Felix. The Cat function completes and felix contains a Cat object with a name of Felix.

So why didn’t the Mammal function run? Well, it did, but only once when setting up inheritance. If you want the superclass’s constructor to run as part of the subclass’s initialization, you have to do that explicitly:

function Cat(name) {
    Mammal.call(this, name);
    this.name = name;
}

Of course, you’d still get the same result, because you’d have the Mammal function set the name property and then Cat would write over it again. You could swap it around, too, so the Mammal overwrites what Cat did:

function Cat(name) {
    this.name = name;
    Mammal.call(this, name);
}

But then the Cat line of this.name = name; is useless and you might as well remove it.

So why didn’t your constructor change do anything? Because that’s not what constructor does. In fact, reading through the ES5 specification, I didn’t see the constructor property actually being used for anything at all. Changing constructor doesn’t do anything, so that’s why it didn’t matter.

Sign up to request clarification or add additional context in comments.

1 Comment

Exactly. This was my question too. Constructors in ES5 is useless and practically it doesn't do anything special!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.