在子类中调用super()后,属性查找实际上是如何工作的

时间:2018-11-26 09:46:44

标签: javascript ecmascript-6 es6-class

我有一个来自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 :(得分:3)

  

这是指狗类

否,this是指实例化的对象。实例化的对象的内部原型为Dog.prototype,而Dog.prototype的内部原型为Animal.prototype

由于this直接指向实例化的对象(在 构造函数和所有方法中),

this.name = name;

直接在该对象上放置name属性 ,因此完全可以引用d.name,或者在其中一种方法中引用this.name:< / p>

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'));

答案 1 :(得分: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));

所以基本上

Dog函数内部的

return _super.call(this, name)解释了Dog类的this方法内部的speak引用的混乱。它通过call()

更改上下文