Конспект JS-course

Прототипное наследование

Источник: http://dmitrypodgorniy.com/blog/2012/07/22/1/

Автор: @dmitry (Дмитрий Подгорный)

В форме таких заключений прототипное наследование лежит у меня в голове. Примеры, подкрепляющие положения, смотреть в фаерфоксе или хроме, ибо __proto__ не является частью стандарта. Разработчики хрома и фаерфокса позволили напрямую обращение к этому свойству.

1) Каждый объект имеет скрытое свойство __proto__, которое ссылается на некий другой объект (исключение — объект Object.prototype, у которого __proto__ ссылается на null). Это и называется цепочкой прототипов.

var arr = [],
       obj = {};
typeof arr.__proto__ === 'object'; // true
typeof obj.__proto__ === 'object'; // true
arr.__proto__ === Array.prototype // true. Экземпляр класса "Массив" наследует от Array.prototype
arr.__proto__.__proto__ === Object.prototype // true он-же наследует от Object.prototype
arr.__proto__.__proto__.__proto__ // null Последнее звено цепи прототипов

2) При чтении свойства в объекте, оно ищется непосредственно в объекте. Если в объекте не находится, то интерпретатор ищет свойство в __proto__. Поиск останавалиается при первом нахождении или когда ссылка __proto__ ведет на null;

function F() {}
F.prototype.state = false; // состояние по умолчанию
F.prototype.state_on = function () {
    this.state = true; // запись свойства в эжкземпляр класса
}
F.prototype.reset_state = function () {
    delete this.state; // удаление свойства из экземпляра класса
}

var f = new F;
f.state;         // false
f.state_on();    // добавили свойство в экземпляр класса
f.state;         // true
f.reset_state(); // удаление свойства из объекта
f.state;         // false (значение взялось из прототипа)
f.test;          // undefined (свойства нет в объекте и цепочке прототипов)

3) __proto__ устанавливает в момент создания объекта, и ссылается туда-же, куда и Конструктор_объекта.prototype;

4) Каждая функция при объявлении получает свойство prototype.

function F () {};
typeof F.prototype === 'object'; // true
var f = new F;
f.__proto__ === F.prototype; // true