Как на самом деле работает поиск свойств после вызова super () в подклассе - PullRequest
0 голосов
/ 26 ноября 2018

У меня есть простой пример из 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 ]

0 голосов
/ 26 ноября 2018

На самом деле, то, что я хотел спросить, было под капотом.Итак, вот ответ, основанный на указателе @ 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) внутри функции Dog объясняет путаницу this ссылки внутри speak метода класса Dog.Это меняет контекст через call()

0 голосов
/ 26 ноября 2018

это относится к классу Dog

Нет, 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'));
...