JS原型继承的意外结果
unexpected results with JS prototype inheritance
我有一个基类,如下所示:
舞台.js:
function Stage(name) {
this.my_name = name;
}
Stage.prototype.name = function() {
return this.my_name;
}
module.exports = Stage;
平行:
var Stage = require("./Stage");
ParallelStage.prototype = Stage.prototype;
ParallelStage.prototype.execute = function() {
console.log("+++ Executing stage " + this.name()+ " in parallel...");
return this;
}
function ParallelStage(name) {
Stage.call(this,name);
return this;
}
module.exports = ParallelStage;
和串行.js:
var Stage = require("./Stage");
SerialStage.prototype = Stage.prototype;
SerialStage.prototype.execute = function() {
console.log("+++ Executing stage " + this.name()+ " in serial...");
return this;
}
function SerialStage(name) {
Stage.call(this,name);
return this;
}
module.exports = SerialStage;
但是当我运行时:
var Parallel = require ("./ParallelStage");
var Serial = require ("./SerialStage");
var parallel = new Parallel("Extraction");
parallel.execute();
我得到以下输出:
+++ Executing stage Extraction in serial...
我显然错过了一些关于javascript和原型继承的基本知识。有人可以告诉我我在这里错过了什么吗?我期待它并行显示舞台执行而不是串行......
为了正确的原型继承,你必须使用
var child.prototype = Object.create(parent.prototype, {...object with properties/methods...}
当您致电时
SerialStage.prototype = Stage.prototype;
您丢失了SerialStage.prototype
对象,因为它引用了Stage.prototype
,因此您的最后一个继承对象始终覆盖原型的属性和方法。因此,编辑代码并更改继承方式
ParallelStage.prototype = Object.create(Stage.prototype);
和
ParallelStage.prototype = Object.create(Stage.prototype);
当你这样做时:
SerialStage.prototype = Stage.prototype;
您不是在创建基本原型的副本 - 它是一个赋值,并且像任何其他赋值一样,它指向现有对象。因此,您不是为ParallelStage
和SerialStage
提供唯一的原型,而是为两个构造函数重用相同的原型。当你分配执行方法时,你已经覆盖了现有的一次,而不是创建一个新的。
一个快速简便的解决方法是执行此操作:
ParallelStage.prototype = new Stage();
和
SerialStage.prototype = new Stage();
这将为每个原型创建一个新对象,然后您可以放置这些方法。原型委派将确保属性查找在原型链上。
问题是你如何使用Stage的原型在下面一行:
ParallelStage.prototype = Stage.prototype
ParallelStage.prototype
现在只是一个指向Stage.prototype
的指针。修改它时,您将使用 Stage 原型替换所有对象的父级函数。
出现您的特定问题是因为 Serial.js 是在 Stage.js 和 Parallel.js 之后执行的;它对 Stage.prototype
的更改是最后的更改,并且对 Stage
、SerialStage
和 ParallelStage
类型的任何对象都有效。
从父级继承原型的正确方法(或正确的方法之一)是使用以下方法:
Child.prototype = Object.create(Parent.prototype)
更改代码以使用此模式,您应该获得所需的行为。
您正在将serialStage
和ParallelStage
的原型设置为Stage.prototype
,因此现在您基本上为所有三种方法使用相同的原型对象。
当您向该原型写入某些内容时,它会覆盖可能具有相同名称的任何内容,例如
var Stage = function Stage() {}
ParallelStage.prototype = Stage.prototype; // set to Stage.prototype
ParallelStage.prototype.execute = function() {}
// ^ you've attached an "execute" method to the Stage.prototype object
SerialStage.prototype = Stage.prototype; // set to the same Stage.prototype
SerialStage.prototype.execute = function() {}
// ^ you've just overwritten the "execute" function in Stage.prototype
您可以使用Object.create
、Object.assign
和许多其他解决方案来创建原型对象的副本,以免每次都覆盖其属性,但这首先违背了继承它的目的。
- Node.js使用Series函数(模式?)实现流控制时出现意外结果
- Javascript:函数返回意外结果
- 意外结果,在 ASP.Net 中解析 JSON 对象的数组
- 按位或意外结果
- 来自 JavaScript 循环的意外结果
- 从 JavaScript 中的图像中读取像素数据会返回半透明像素的意外结果
- 在 JS 中短路空数组会产生意外结果:“[] ||真 == []'
- NodeJS中的Parse Json文件在Node中显示意外结果
- 基于给出意外结果的提示输入的逻辑
- JavaScript Regexp.test返回意外结果
- 键控产生意外结果.HTML5游戏
- Javascript do/while循环显示意外结果
- 来自 CSS 和 jQuery 的意外结果
- MongoDB mapReduce方法意外结果
- 具有意外结果的 Javascript 函数参数
- 在 JavaScript 中解析日期字符串的意外结果
- 从内部HTML更改为表单时获得意外结果,输入类型文本字段
- 在计算链逻辑表达式 JavaScript 时出现意外结果
- 意外结果 - 谷歌自动完成针对约克郡
- JavaScript unshift 参数返回意外结果