The shared nature of prototypes makes them ideal for defining methods once for all objects of a given type.
It's much more efficient to put the methods on the prototype and then use this to access the current instance.
For example, consider the following new Book constructor:
function Book(name) { // ww w .j a v a2 s. com
this.name = name;
}
Book.prototype.writeLine = function() {
console.log(this.name);
};
var book1 = new Book("Javascript");
var book2 = new Book("CSS");
console.log(book1.name); // "Javascript"
console.log(book2.name); // "CSS"
book1.writeLine(); // outputs "Javascript"
book2.writeLine(); // outputs "CSS"
The code above generates the following result.
We can also store other types of data on the prototype, but be careful when using reference values because these values are shared across instances.
function Book(name) { // w ww .j a v a 2 s . c om
this.name = name;
}
Book.prototype.writeLine = function() {
console.log(this.name);
};
Book.prototype.favorites = [];
var book1 = new Book("Javascript");
var book2 = new Book("CSS");
book1.favorites.push("A");
book2.favorites.push("B");
console.log(book1.favorites); // "A,B"
console.log(book2.favorites); // "A,B"
The code above generates the following result.
The following code shows how to add more methods to prototype:
function Book(name) { /* w ww .ja va 2 s . c o m*/
this.name = name;
}
Book.prototype = {
writeLine : function() {
console.log(this.name);
},
toString : function() {
return "[Book " + this.name + "]";
}
};
The code above defines two methods on the prototype, writeLine() and
toString()
.
There is one side effect to be aware of:
function Book(name) { //w ww.java 2s . c o m
this.name = name;
}
Book.prototype = {
writeLine : function() {
console.log(this.name);
},
toString : function() {
return "[Book " + this.name + "]";
}
};
var book1 = new Book("Javascript");
console.log(book1 instanceof Book); // true
console.log(book1.constructor === Book); // false
console.log(book1.constructor === Object); // true
The code above generates the following result.
To avoid this, restore the constructor property to a proper value when overwriting the prototype:
function Book(name) { //from w ww. j a va 2s .com
this.name = name;
}
Book.prototype = {
constructor : Book,
writeLine : function() {
console.log(this.name);
},
toString : function() {
return "[Book " + this.name + "]";
}
};
var book1 = new Book("Javascript");
var book2 = new Book("CSS");
console.log(book1 instanceof Book); // true
console.log(book1.constructor === Book); // true
console.log(book1.constructor === Object); // false
console.log(book2 instanceof Book); // true
console.log(book2.constructor === Book); // true
console.log(book2.constructor === Object); // false
The code above generates the following result.
Since all instances of a particular type reference a shared prototype, we can augment all of those objects.
The [[Prototype]] property contains a pointer to the prototype, and any changes to the prototype are available on any instance referencing it.
We can add new members to a prototype at any point and have those changes reflected on existing instances.
function Book(name) { /*from w ww. ja v a 2 s. co m*/
this.name = name;
}
Book.prototype = {
constructor : Book,
writeLine : function() {
console.log(this.name);
},
toString : function() {
return "[Book " + this.name + "]";
}
};
var book1 = new Book("Javascript");
var book2 = new Book("CSS");
console.log("sayHi" in book1); // false
console.log("sayHi" in book2); // false
// add a new method
Book.prototype.sayHi = function() {
console.log("Hi");
};
book1.sayHi(); // outputs "Hi"
book2.sayHi(); // outputs "Hi"
The code above generates the following result.
We can use prototypes to modify the built-in objects from the JavaScript engine.
The following code shows how to add a new method for arrays by modifying Array.prototype.
Array.prototype.sum = function() { /* ww w. j a v a2 s . co m*/
return this.reduce(function(previous, current) {
return previous + current;
});
};
var numbers = [ 1, 2, 3, 4, 5, 6 ];
var result = numbers.sum();
console.log(result);
The code above generates the following result.
The following code shows how to add new method for string value.
String.prototype.capitalize = function() {
return this.charAt(0).toUpperCase() + this.substring(1);
};
var message = "hello world!";
console.log(message.capitalize());
The code above generates the following result.