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

В разд. 11.1.7 мы уже рассматривали возможность расширения объекта за счет наследования свойств другого объекта. В этом случае базовый объект указывается в качестве прототипа производного объекта:

let objA = { a: 10 };
let objB = { b: 55 };
Object.setPrototypeOf(objB, objA);
console.log(objB.a);                        // 10
console.log(objB.b);                        // 55
console.log( Object.getPrototypeOf(objB) ); // { a: 10 }

Эту цепочку наследования мы можем еще больше расширить:

let objA = { a: 10 };
let objB = { b: 55 };
let objC = { c: 8 };
Object.setPrototypeOf(objB, objA);
Object.setPrototypeOf(objC, objB);
console.log(objC.a);                        // 10
console.log(objC.b);                        // 55
console.log(objC.c);                        // 8

Наследование в языке JavaScript построено на прототипах. Все прототипы объектов по умолчанию ссылаются на прототип класса Object:

console.log(
   Object.getPrototypeOf(objA) === Object.prototype); // true
console.log(Object.prototype.isPrototypeOf(objA) );   // true

В этом примере мы воспользовались методом isPrototypeOf(<Объект>), который возвращает значение true, если прототип входит в цепочку наследования объекта <Объект>, и false — в противном случае.

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

objC
    c: 8
    __proto__:
        objB
            b: 55
            __proto__:
                objA
                    a: 10
                    __proto__:
                        Object.prototype:
                            __proto__: null
// objC => objB => objA => Object.prototype => null

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

Теперь рассмотрим наследование классов (листинг 11.3).

Листинг 11.3. Наследование

function A(_a) {
   this.a = _a;
}
function B(_a, _b) {
   A.call(this, _a);     // Вызываем конструктор класса A
   this.b = _b;
}
function C(_a, _b, _c) {
   B.call(this, _a, _b); // Вызываем конструктор класса B
   this.c = _c;
}

B.prototype = Object.create(A.prototype);
B.prototype.constructor = B;
C.prototype = Object.create(B.prototype);
C.prototype.constructor = C;

let obj = new C(10, 55, 8);
console.log(obj.a);            // 10
console.log(obj.b);            // 55
console.log(obj.c);            // 8
console.log(obj);              // C { a: 10, b: 55, c: 8 }
console.log(obj instanceof C); // true
console.log(obj instanceof B); // true
console.log(obj instanceof A); // true

Обратите внимание: внутри конструкторов производных классов необходимо вызвать конструктор базового класса до первого обращения к указателю this. Передача указателя и параметров осуществляется с помощью метода call() или apply() (см. разд. 10.5).

Следующие инструкции реализуют прототипное наследование:

B.prototype = Object.create(A.prototype);
B.prototype.constructor = B;
C.prototype = Object.create(B.prototype);
C.prototype.constructor = C;

Если эти инструкции не указать, то оператор instanceof в двух последних инструкциях из листинга 11.3 вернет значение false:

console.log(obj instanceof C); // true
console.log(obj instanceof B); // false
console.log(obj instanceof A); // false

Учебник по Node.js и JavaScript
Учебник по JavaScript (Node.js) в формате PDF

Помощь сайту

ЮMoney (Yandex-деньги): 410011140483022

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов