0

Today I saw two different types of Javascript function declarations and I'd like to have a deeper understanding of the two:

function Car( model, year, miles ){
   this.model = model;
   this.year    = year;
   this.miles  = miles;
}

/*
 Note here that we are using Object.prototype.newMethod rather than 
 Object.prototype so as to avoid redefining the prototype object
*/
Car.prototype.toString = function(){
    return this.model + " has done " + this.miles + " miles";
};

var civic = new Car( "Honda Civic", 2009, 20000);
var mondeo = new Car( "Ford Mondeo", 2010, 5000);

console.log(civic.toString());

and type 2:

function Car( model, year, miles ){
   this.model = model;
   this.year    = year;
   this.miles  = miles;
   this.toString = function(){
       return this.model + " has done " + this.miles + " miles";
   };
}


var civic = new Car( "Honda Civic", 2009, 20000);
var mondeo = new Car( "Ford Mondeo", 2010, 5000);

console.log(civic.toString());

Specifically the 'prototype' and the 'this.toString'.

Can anyone impart some pearls of JS wisdom?

1

2 Answers 2

6

The primary difference here is that in method 2 you are redefining the method with every new instance of Car you create, which is technically less performant.

One nice thing method 2 does afford you however is that you can create truly private instance variables, like so:

function Person( _age ){
    var age = _age;
    this.canDrink = function(){
        return age >= 21;
    }
}

var p = new Person(25);
p.canDrink() // true
p.age // undefined, because age is not exposed directly

Another advantage to method 1 (besides performance) is that you can now change the functionality of all instances of on object. For example:

function Person( _age ){
    this.age = _age;
}
Person.prototype.canDrink = function(){
    return this.age >= 21;
}

var a = new Person(15),
    b = new Person(25);
a.canDrink() // false
b.canDrink() // true

Person.prototype.canDrink = function(){ return true }
a.canDrink() // true
b.canDrink() // true

this would not be possible with method 2 (without changing it for every instance). Age however, is now exposed:

a.age // 15
b.age // 25
Sign up to request clarification or add additional context in comments.

Comments

0

this.toString must be defined within the constructor and will only be found on the Car class, not anything inheriting from it (unless specifically included on children classes).

Car.prototype.toString can be defined outside of the constructor and will be found on the prototypes of any classes inheriting from the Car class.

5 Comments

It depends what you mean by inheritance, since Javascript has no inheritance standard. The way I normally use inheritance, this.toString() is inherited.
True, true. That's more similar to classical inheritance (although not really :p ), whereas I'm talking about prototypal inheritance.
Are you meaning Corvette.prototype = new Car();? I do Corvette.prototype = new Car(); Corvette.prototype.constructor = Corvette;. That seems to be a very effective method of inheritance.
You could also do something like Car.extend(Corvette);, if I remember the syntax correctly. That's also pretty effective, and efficient to boot.
Oops, that's right. I knew I had read that somewhere but I didn't attribute it to jQuery. Your method is good, I do something similar actually.

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.