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?

benhowdle89
  • 36,900
  • 69
  • 202
  • 331
  • possible duplicate of [Use of 'prototype' vs. 'this' in Javascript?](http://stackoverflow.com/questions/310870/use-of-prototype-vs-this-in-javascript) – Niko Apr 21 '12 at 23:10

2 Answers2

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
netpro2k
  • 141
  • 4
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.

Elliot Bonneville
  • 51,872
  • 23
  • 96
  • 123
  • It depends what you mean by inheritance, since Javascript has no inheritance standard. The way I normally use inheritance, `this.toString()` *is* inherited. – Kendall Frey Apr 21 '12 at 23:03
  • True, true. That's more similar to classical inheritance (although not really :p ), whereas I'm talking about prototypal inheritance. – Elliot Bonneville Apr 21 '12 at 23:05
  • 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. – Kendall Frey Apr 21 '12 at 23:08
  • You could also do something like `Car.extend(Corvette);`, if I remember the syntax correctly. That's also pretty effective, and efficient to boot. – Elliot Bonneville Apr 21 '12 at 23:10
  • 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. – Elliot Bonneville Apr 21 '12 at 23:14