2

I'm Codeyear fellow and unfortunately prototype object concept is not explained.I google it and found tutorial. After learning,my understanding says that we use prototype object inheritance to save memory and share common properties between objects . am i right ? if yes , dont you think the below code is the bad practice. Since car constructor has already defined price,speed and & getPrice,why we need to define same thing again,since we are using the concept of inheritance . please explain . below is the code .

function Car( listedPrice ) {
    var price = listedPrice;
    this.speed = 0;

    this.getPrice = function() {
        return price;
    };
}

Car.prototype.accelerate = function() {
    this.speed += 10;
};

function ElectricCar( listedPrice ) {
    var price = listedPrice;
    this.speed = 0;

    this.getPrice = function() {
        return price;
    };
}

ElectricCar.prototype = new Car(); // Please also explain why car constructor 
                                   // is not thowing error since we are not passing
                                   // listedPrice parameter

myElectricCar = new ElectricCar(500);

console.log(myElectricCar instanceof Car);
Colin Brock
  • 21,267
  • 9
  • 46
  • 61
Paritosh Piplewar
  • 7,982
  • 5
  • 26
  • 41
  • This may help you: http://stackoverflow.com/questions/10836064/what-does-anobject-prototype-constructor-do – Sarfraz Jun 09 '12 at 15:03

2 Answers2

3

The constructor and the prototype are two separate concepts. When you apply the prototypal inheritance with ElectricCar.prototype = new Car();, it inherits only the methods defined on the object and its prototype, not the constructor itself.

You can actually see the way this works with some quick console.log() calls:

console.log(ElectricCar);
console.log(ElectricCar.prototype);
console.log(ElectricCar.prototype.__proto__);

This returns:

[Function: ElectricCar]
{ speed: 0, getPrice: [Function] }
{ accelerate: [Function] }

The first line is the constructor.

The second is the actual prototype, as set by ElectricCar.prototype = new Car(); above. Remember that in the constructor of Car, this.speed and this.getPrice were set, which explains the values of ElectricCar.prototype.speed and ElectricCar.prototype.getPrice.

What is perhaps least clear is the last line, the ElectricCar.prototype.__proto__. This is the prototype of the prototype. Car objects have a prototype object in which accelerate was defined. This prototype is copied over to the prototype of ElectricCar in its internal __proto__ property. This is called prototype chaining.

Because the constructor is not part of the prototype, and the prototype is all you're inheriting, the constructor for Car has been copied and pasted into ElectricCar. As you point out, there are definitely cleaner ways to do this. Here's an alternative:

function ElectricCar( listedPrice ) {
    Car.apply(this, arguments);
}

ElectricCar.prototype = new Car();

See apply for more details.

As for your final question (why doesn't new Car() throw an error), as the other answers say, that's kind of how JavaScript works. If you supply fewer arguments to a function than it has parameters, any unset (so to speak) parameters will be set to undefined. To demonstrate:

function returnMe(a) {
    return a;
}

console.log(returnMe(5));
console.log(returnMe(2+2));
console.log(returnMe());
console.log(returnMe(undefined));

This will return:

5
4
undefined
undefined

As you can see undefined is actually a variable that you can pass around (as in returnMe(undefined)). For more on this, see undefined.

Jonathan S.
  • 2,238
  • 16
  • 16
0

getPrice is such way to create a closure over price var in its outer scope, effectively making price a private member, separate for each different instances, that only this function can ever have access to.

Constructor doesn't throw an error, because supplying arguments to a function in JavaScript is never mandatory. You supply as much as you want and as long as there's named arguments, first from the list you've supplied are assigned to that names.

Oleg V. Volkov
  • 21,719
  • 4
  • 44
  • 68