0

In trying to understand javascript constructors, I have been looking at this question.

It seemed to me that I understood it reasonably, but, ironically, when I tried to run similar code, it did not work for me at all.

This is my code

function Car(name) {
    this.Name = name;
    this.Year = 1999;
}

Car.prototype.Drive = function() {
    document.write("My name is '" + this.Name + "' and my year is '" + this.Year + "'. <br />");
};

SuperCar = function () { };
SuperCar.prototype = new Car();

function SuperCar(name) {
    Car.call(this, name);
}

var MyCar = new Car("mycar");
var MySuperCar = new SuperCar("my super car");

MyCar.Drive();
MySuperCar.Drive();

First of all, this line

SuperCar = function () { };

was necessary for it to run at all. If I leave it out, I the error "SuperCar is undefined" at this line.

SuperCar.prototype = new Car();

I don't really understand why declaring SuperCar as an empty function was necessary.

Secondly, when I do run the code I get this result

My name is 'mycar' and my year is '1999'. 
My name is 'undefined' and my year is '1999'. 

Apparently, for MySuperCar, the SuperCar(name) function is never called, but the Car() is.

Adding this line does not help

SuperCar.prototype.constructor = SuperCar;

Neither does this

SuperCar.prototype.constructor = function(name) {
    Car.call(this, name);
};

(I have been running the code inside a script-tag on IE 9 and Chrome 22)

How should I properly define a SuperCar constructor taking a name parameter? Or, put it another way, how can I make the new SuperCar("my super car") call behave the way I expected (setting the name to "my super car")?

2
  • Fiddle: jsfiddle.net/userdude/Gs4qu You might stay away from document.write in general, I would suggest document.body.innerHTML = "blah blah blah<br>"; instead, or DOM methods. Commented Sep 30, 2012 at 11:46
  • 1
    It's also working if I comment out the function variable you're asking about: jsfiddle.net/userdude/Gs4qu/1 Right below that you've got function SuperCar(name){...} declared, and hoisting puts it at the top of the scope. So unless for some time that function didn't exist or was originally a variable function or function variable (who can tell the difference?), I don't see why that would be a problem. I'm talking about Chrome here, too. Commented Sep 30, 2012 at 11:50

2 Answers 2

4

You should not really create an instance of Car as the prototype, but only create an object that inherits from Car.prototype. For the details, see What is the reason to use the 'new' keyword at Derived.prototype = new Base. Instead, use

SuperCar.prototype = Object.create(Car.prototype);

Your problem is that your SuperCars are created by the empty function - which returns an object without any properties. Yet, they inherit from new Car(), whose name is undefined. This happened in your fiddle because the function declaration (beginning with the function keyword, check out this explanation) is hoisted (available everywhere in the scope) and overwritten by the line

SuperCar = function () { };

so that your SuperCar constructor does not call the Car constructor any more. Fixed fiddle

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

Comments

2

You did not need the empty function. You made an empty SuperCar function and then set its prototype, but then over-wrote it with a new definition of SuperCar.

function SuperCar() {}
SuperCar.prototype = new Car();

function SuperCar() {} // original SuperCar overwritten

4 Comments

No, you do not need to set the constructor property to a new instance.
And no, the second function declaration does not overwrite the first one as well.
@Bergi But it was definitively that empty function that did it because when I take it out it works fine.
Yes, but it was the function expression above the original function declaration - see my answer

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.