在javascript中理解原型/构造函数

时间:2018-05-22 21:30:55

标签: javascript constructor prototype

function A(){}

function B(){}

function C(){}

B.prototype = new A();
console.log(B.prototype.constructor);
C.prototype = new B();
console.log(C.prototype.constructor);

打印:

  

[功能:A]
[功能:A]

到目前为止,我的理解是,通常在JavaScript中,对象的构造函数属性引用它所创建的构造函数。如果对象是由文字创建的,则构造函数属性引用该文字的基础类型。

鉴于上面构造函数属性的“定义”,我不明白为什么它打印了 [Function:A] 两次,而不是:

  

[功能:A]
[功能:B]

1 个答案:

答案 0 :(得分:2)

设置prototype后,您将清除之前的内容。并且,通过这样做,在切换原型之前擦除对原始构造函数的引用(constructor是存储在原型中的对象引用,如果更改原型,则也更改构造函数)。

当像这样手动进行继承时,你必须记住"修复"交换原型后的constructor属性。您的代码没有这样做,因此当您致电new B()时,您实际上是使用A()作为构造函数。然后,当您将C的原型设置为new B()时,A()构造函数会运行并返回A的实例。



function A(){}

function B(){}

function C(){}

console.log("B.prototype.constructor before inheritance: ",  B.prototype.constructor);
B.prototype = new A();

C.prototype = new B();

console.log(A.prototype.constructor);  // A
console.log(B.prototype.constructor);  // A
console.log(C.prototype.constructor);  // A

console.log("B.prototype.constructor after inheritance: ",  B.prototype.constructor);



// We've completely changed the prototype (including the constructor), so we have to fix it:
B.prototype.constructor = B;
console.log("B.prototype.constructor after constructor fix: ",  B.prototype.constructor);




使用JavaScript类,我们通过在子类的构造函数中调用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.');
  }
}

var d = new Dog('Mitzie');
d.speak(); // Mitzie barks.