原型继承未按预期工作

Prototype inheritance is not working as expected

从我的 JavaScript 童年开始,我就阅读并遵循了在原型继承的情况下我应该重写构造函数。但令我惊讶的是,即使注释了重写的构造函数语句,以下示例也会在控制台输出相同的内容。请指教

function A() {
    console.info("A constructor");
}

function B() {
    console.info("B constructor");
}

B.prototype = A.prototype;
B.prototype.constructor = B; // Do we really need this statement?

console.info("cp 1");
var b = new B();
console.info("cp 2");

在进入构造函数部分之前,您的代码中存在问题。您正在使 B.prototypeA.prototype 相同,方法是

B.prototype = A.prototype;

这意味着,您无法有效识别这些函数构造的对象的父级。试试这个

console.log(new B() instanceof A, new B() instanceof B);
// true true

这是预料之中的,因为 B 是由 B 创建的,而 B 是根据 A 的原型创建的。但是

console.log(new A() instanceof A, new A() instanceof B);
// true true

什么?为什么 A 的对象是 B 的实例?因为,既然你让 B.prototype 也和 A.prototype 一样,当一个对象 A 试图找出它的原型(A.prototype 是从 A) 存在于 B 的原型链中的任何地方。由于 B.prototypeA.prototype 相同,因此可以将 A 的对象视为 B 的对象。

正确的做法是,

B.prototype = Object.create(A.prototype);

现在,您正在使 B 的原型成为使用 A 的原型创建的对象。所以,它不是A'原型,而是基于A.

原型创建的对象

现在,如果我们不这样做会怎样

B.prototype.constructor = B;

尝试打印由 B 创建的对象的 constructor 属性,不包含该行

console.log((new B()).constructor);
// [Function: A]

由于 B 的原型仍然具有从 Aprototype 复制的构造函数值,它仍然引用函数 A。这就是我们用 B 函数对象替换它的原因。