Источник: 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