Как на самом деле работает поиск свойств после вызова super() в подклассе
У меня есть простой пример из MDN.
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a noise.');
}
}
class Dog extends Animal {
constructor(name) {
super(name); // call the super class constructor and pass in the name parameter
}
speak() {
console.log(this.name + ' barks.');
}
}
let d = new Dog('Mitzie');
d.speak(); // Mitzie barks.
Теперь в подклассе Dog
как this.name
работает под капотом. поскольку this
относится к Dog
Экземпляр и имя класса - это не то, что существует в экземпляре Dog. Таким образом, для доступа к этому мы используем супер вызов, который вызывает конструктор родителя. Я понимаю, что это выглядит.
Но кто-то может объяснить, пожалуйста, через механизм прототипа (мне удобно понимать механизм поиска и формирования прототипа).
Я уверен, что в глубине это будет сводиться к этому, но не ясно, какие промежуточные шаги между ними. Спасибо!
2 ответа
это относится к классу собак
Нет, this
относится к экземпляру объекта. Созданный объект имеет внутренний прототип Dog.prototype
, а также Dog.prototype
имеет внутренний прототип Animal.prototype
,
поскольку this
ссылается непосредственно на экземпляр объекта (как в конструкторах, так и во всех методах),
this.name = name;
ставит name
свойство непосредственно на этот объект, так что это вполне нормально ссылаться d.name
или внутри одного из методов, this.name
:
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a noise.');
}
}
class Dog extends Animal {
constructor(name) {
super(name); // call the super class constructor and pass in the name parameter
}
speak() {
console.log(this.name + ' barks.');
}
}
const d = new Dog('Mitzie');
const dProto = Object.getPrototypeOf(d);
const secondProto = Object.getPrototypeOf(dProto);
console.log(dProto === Dog.prototype);
console.log(secondProto === Animal.prototype);
console.log(d.hasOwnProperty('name'));
На самом деле, то, что я хотел спросить, было под капотом. Итак, вот ответ, основанный на указателе @Jai в комментариях, которые я искал.
Я запустил код на основе классов через es5compiler или любой другой компилятор и получил это преобразование
var Dog = /** @class */ (function (_super) {
__extends(Dog, _super);
function Dog(name) {
return _super.call(this, name) || this;
}
Dog.prototype.speak = function () {
console.log(this.name + ' barks.');
};
return Dog;
}(Animal));
Так в основном
return _super.call(this, name)
Функция внутри собаки объясняет путаницу this
ссылка внутри speak
метод класса собаки. Это меняет контекст через call()