Книга: JavaScript. Подробное руководство, 6-е издание

6.2.2. Наследование

6.2.2. Наследование

Объекты в языке JavaScript обладают множеством «собственных свойств» и могут также наследовать множество свойств от объекта-прототипа. Чтобы разобраться в этом, необходимо внимательно изучить механизм доступа к свойствам. В примерах этого раздела для создания объектов с определенными прототипами используется функция inherit() из примера 6.1.

Предположим, что программа обращается к свойству х объекта о. Если объект о не имеет собственного свойства с таким именем, выполняется попытка отыскать свойство х в прототипе объекта о. Если объект-прототип не имеет собственного свойства с этим именем, но имеет свой прототип, выполняется попытка отыскать свойство в прототипе прототипа. Так продолжается до тех пор, пока не будет найдено свойство х или пока не будет достигнут объект, не имеющий прототипа. Как видите, атрибут prototype объекта создает цепочку, или связанный список объектов, от которых наследуются свойства.

var о = {}          //о наследует методы объекта Object.prototype
o.х = 1;            //и обладает собственным свойством х.
var р = inherit(о); // р наследует свойства объектов о и Object.prototype
p.у = 2;            //и обладает собственным свойством у.
var q = inherit(p); // q наследует свойства объектов р, о и Object.prototype
q.z = 3;            //и обладает собственным свойством z.
var s = q.toString(); // toString наследуется от Object.prototype
q.x+q.y             // => 3: x и у наследуются от о и p

Теперь предположим, что программа присваивает некоторое значение свойству х объекта о. Если объект о уже имеет собственное свойство (не унаследованное) с именем х, то операция присваивания просто изменит значение существующего свойства. В противном случае в объекте о будет создано новое свойство с именем х. Если прежде объект о наследовал свойство х, унаследованное свойство теперь окажется скрыто вновь созданным собственным свойством с тем же именем.

Операция присваивания значения свойству проверит наличие этого свойства в цепочке прототипов, чтобы убедиться в допустимости присваивания. Например, если объект о наследует свойство х, доступное только для чтения, то присваивание выполняться не будет. (Подробнее о том, когда свойство может устанавливаться, рассказывается в разделе 6.2.3.) Однако если присваивание допустимо, всегда создается или изменяется свойство в оригинальном объекте и никогда в цепочке прототипов. Тот факт, что механизм наследования действует при чтении свойств, но не действует при записи новых значений, является ключевой особенностью языка JavaScript, потому что она позволяет выборочно переопределять унаследованные свойства:

var unitcircle = { r:1 };    // Объект, от которого наследуется свойство
var с = inherit(unitcircle); // с наследует свойство г
с.х = 1; с.у = 1;            //с определяет два собственных свойства
с.r = 2;                     //с переопределяет унаследованное свойство
unitcircle.r;                // => 1: объект-прототип не изменился

Существует одно исключение из этого правила, когда операция присваивания значения свойству терпит неудачу или приводит к созданию/изменению свойства оригинального объекта. Если объект о наследует свойство х и доступ к этому свойству осуществляется посредством методов доступа (раздел 6.6), то вместо создания нового свойства х в объекте о производится вызов метода записи нового значения. Однако обратите внимание, что метод записи вызывается относительно объекта о, а не относительно прототипа, в котором определено это свойство, поэтому, если метод записи определяет какие-либо свойства, они будут созданы в объекте о, а цепочка прототипов опять останется неизменной.

Оглавление книги


Генерация: 0.121. Запросов К БД/Cache: 0 / 2
поделиться
Вверх Вниз