0

我有一个来自 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 实例上的东西。因此,要访问它,我们使用调用父构造函数的超级调用。我知道它看起来。

但是有人可以通过原型机制来解释(我很容易理解原型查找和链接机制)。

我确信在内心深处它会归结为这一点,但不清楚中间的步骤。谢谢!

4

2 回答 2

3

这是指 Dog 类

不,this是指实例化的对象。实例化对象的内部原型为Dog.prototypeDog.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'));

于 2018-11-26T09:52:48.437 回答
0

实际上,我想问的是引擎盖下的问题。因此,这是基于@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)inside Dog 函数解释了类 Dog的this内部方法引用的混淆。speak它通过改变上下文call()

于 2018-11-26T10:39:31.143 回答