Этот сайт использует cookies. Продолжение работы с сайтом означает, что Вы согласны!
Наследование
В разд. 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
Помощь сайту
ЮMoney (Yandex-деньги): 410011140483022
ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов