三个问题:
-
A1 放置在实例上的 run 不会返回任何内容,因此调用它会产生 undefined。
-
A1 将run 放在实例 上,这意味着在您的b1 实例中,B1.prototype.run 已被run 遮挡,A1 直接分配给实例。
-
this.constructor.run() 不是 A1 版本。
如果你把run放在A1.prototype上,你就可以做到:
function A1() {
}
A1.prototype.eat = function() {
console.log('A1 eats');
};
A1.prototype.run = function() {
return 'A1 runs';
};
function B1() {
A1.call(this);
}
B1.prototype = Object.create(A1.prototype);
B1.prototype.run = function() {
return A1.prototype.run.call(this) + ",B1 also runs";
};
var b1 = new B1();
console.log(b1.run());
这很丑,这就是为什么I wrote a script to automate supercalls back in the day,但这就是你在这个级别工作时的做法。
不过,现在,您会使用 ES2015 的 class 语法和 super 来代替,如果需要支持过时的 JavaScript 引擎,则使用 Babel 或 Traceur 或类似方法进行转译:
class A1 {
eat() {
console.log("A1 eats");
}
run() {
return "A1 runs";
}
}
class B1 extends A1 {
run() {
return super.run() + ",B1 also runs";
}
}
var b1 = new B1();
console.log(b1.run());
您的编辑说您不希望run 出现在原型上,它必须由A1 分配,如下所示:
function A1() {
this.run = function() {
return 'A1 runs';
};
}
这有点麻烦,但您仍然可以做到。由于我上面提到的原因,在实例上设置 run 会掩盖您的实例通常使用的 B1.prototype.run。所以要使用它,还要调用A1的non-prototype run,你必须在实例上替换它。
因此,在B1 中定义B1 的run 比在B1.prototype 上更有意义,就像A1 在A1 中定义它一样,而不是在A1.prototype 中定义它:
function B1() {
var A1run;
A1.call(this);
A1run = this.run;
this.run = function() {
return A1run.call(this) + ",B1 also runs";
};
}
活生生的例子:
function A1() {
this.run = function() {
return 'A1 runs';
};
}
A1.prototype.eat = function() {
console.log('A1 eats');
};
function B1() {
var A1run;
A1.call(this);
A1run = this.run;
this.run = function() {
return A1run.call(this) + ",B1 also runs";
};
}
B1.prototype = Object.create(A1.prototype);
var b1 = new B1();
console.log(b1.run());
但如果你真的,真的希望它(至少部分)出现在B1.prototype:
function B1() {
var A1run;
A1.call(this);
A1run = this.run;
this.run = function() {
return A1run.call(this) + B1.prototype.run.call(this);
};
}
// ...
B1.prototype.run = function() {
return ",B1 also runs";
};
活生生的例子:
function A1() {
this.run = function() {
return 'A1 runs';
};
}
A1.prototype.eat = function() {
console.log('A1 eats');
};
function B1() {
var A1run;
A1.call(this);
A1run = this.run;
this.run = function() {
return A1run.call(this) + B1.prototype.run.call(this);
};
}
B1.prototype = Object.create(A1.prototype);
B1.prototype.run = function() {
return ",B1 also runs";
};
var b1 = new B1();
console.log(b1.run());