Как на самом деле работает поиск свойств после вызова 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()

Другие вопросы по тегам