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]
答案 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.