24

As I understand, in JavaScript every object has a prototype and it exposes some default properties. I have the following code where I'm trying to set the Year property of two objects through prototype. But both the calls are failing.

How can I override toLocalString() for any object if I don't have access to the prototype? Please note that the following code is to test on the prototype property, but my intention is to override the toLocalString() method.

var car = {
    Make: 'Nissan',
    Model: 'Altima'
};

car.Year = 2014;
alert(car.Year);

alert(car.prototype); // returns undefined

car.prototype.Year = 2014; // Javascript error

// --------------

function Car() {
    this.Make = 'NISSAN';
    this.Model = 'Atlanta';
}

var v = new Car();
v.prototype.Year = 2014; // JavaScript error
alert(v.prototype);
frogatto
  • 28,539
  • 11
  • 83
  • 129
wonderful world
  • 10,969
  • 20
  • 97
  • 194
  • 1
    In your bottom example, it should be `Car.prototype.Year = 2014` - you set the prototype on the object function - not the created instance. – tymeJV Oct 01 '14 at 19:49
  • Do you mean `toLocaleString()` instead of `toLocalString()` or do you want to implement your own method `toLocalString()`? – keenthinker Oct 01 '14 at 20:02
  • Please have look at [this answer](http://stackoverflow.com/a/26149216/1841194) – frogatto Oct 01 '14 at 20:07
  • 2
    The `prototype` property belongs on a *function*. The function uses that `prototype` property when called with `new` to construct instance objects. Setting `prototype` on a non-function object has no effect. – apsillers Oct 01 '14 at 20:15

2 Answers2

11

You do have access to the prototype property, but it is only present on Functions.

var car = {
    Make: 'Nissan',
    Model: 'Altima'
}; 

This is the same as:

var car = new Object();
car.Make = 'Nissan';
car.Model = 'Altima'; 

So, car.__proto__ === Object.prototype.

And car.prototype === undefined as the prototype property is only present on Functions (as I already said).

function Car() {
    this.Make = 'NISSAN';
    this.Model = 'Atlanta';
}

Here Car.prototype points to an instance of Object because Car is a function and when function declarations are evaluated their prototype is set to an instance of Object.

Car.prototype.Year = 2014; //all Car *instances* will have a Year property set to 2014 on their prototype chain.

var c = new Car(); //create an instance
console.log(c.Year); //2014

Overriding a method present on the prototype chain for an object is as simple as creating a corresponding method on the object:

var myObject = new Object();
myObject.toLocaleString = function() {
  //my own implementation
};
Ben Aston
  • 53,718
  • 65
  • 205
  • 331
6

You probably want to modify the constructor function prototype:

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

Car.prototype.toLocaleString = function() {
  return [this.year, this.make, this.model].join(' ');
};

var civic = new Car(2014, 'Honda', 'Civic');
civic.toLocaleString(); // => "2014 Honda Civic"

This MDN article on Object.prototype might be helpful.

maerics
  • 151,642
  • 46
  • 269
  • 291