Это поведение не ограничивается определяемыми пользователем объектами, оно может быть применено также к встроенным типам. Весьма просто добавить методы экземпляра к массивам, строкам или любым другим встроенным типам:
Array.prototype.double = function () {
var newArray = [];
// inside this function, "this" refers to the array
for ( var i = 0, length = this.length; i < length; i++) {
newArray.push( this [i]);
newArray.push( this [i]);
}
return newArray;
};
var exampleArray = new Array(1, 2, 3);
// inherits all the properties of Array.prototype
exampleArray.double();
//-> [1, 1, 2, 2, 3, 3]
Так как exampleArray является экземпляром Array, он обращается к свойству Array.prototype для наследования. Вместо того, чтобы определять функцию double в глобальном пространстве имен, мы определяем ее как метод экземпляра Array. Такой подход улучшает объединение пользовательского кода с родным кодом, уменьшает его объем, риск коллизий имен, и делает код намного более понятным.
Те из Вас кто хорошо знаком с классическим наследованием, основанного на классах, не должны обеспокоиться об этом: библиотека Prototype включает более традиционную систему ООП, которая учитывает различие между классами и экземплярами классов — и исключает взаимодействие с прототипами. Тем не менее прототипное наследование не является чем-то, чего Вы должны бояться.
Все объекты в JavaScript непостоянны: они могут быть изменены, расширены, и сокращены в любое время. Можно определить любое свойство у объекта, даже то, которое уже существует.
var object = new Object();
object.foo = "foo";
object.bar = "bar";
for ( var i in object) console.log(i);
//-> foo
//-> bar
6