Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/388.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript JS原型继承的意外结果_Javascript_Inheritance_Prototype - Fatal编程技术网

Javascript JS原型继承的意外结果

Javascript JS原型继承的意外结果,javascript,inheritance,prototype,Javascript,Inheritance,Prototype,我有一个基类,比如: Stage.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; ParallelStag

我有一个基类,比如:

Stage.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;
和Serial.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和原型继承的一些基本内容。有人能告诉我我在这里遗漏了什么吗?我希望它显示并行而不是串行的阶段执行…

您正在将
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
和许多其他解决方案来创建原型对象的副本,这样就不会每次都覆盖它的属性,但这样做首先会破坏继承它的目的。

要获得正确的原型继承,您必须使用

var child.prototype = Object.create(parent.prototype, {...object with properties/methods...}
当你打电话的时候

SerialStage.prototype = Stage.prototype;
您松开了引用到
Stage.prototype
SerialStage.prototype
对象,因此您最后继承的对象总是覆盖prototype的属性和方法。 因此,请编辑您的代码并更改继承方式

ParallelStage.prototype = Object.create(Stage.prototype);

当您这样做时:

SerialStage.prototype = Stage.prototype;
您没有创建基础原型的副本-这是一个赋值,与任何其他赋值一样,它指向现有对象。因此,您不是为
ParallelStage
SerialStage
提供唯一的原型,而是为两个构造函数重用相同的原型。当您指定execute方法时,您已经覆盖了现有的方法一次,而不是创建了一个新的方法

一个简单快捷的解决方法是:

ParallelStage.prototype = new Stage();


这将为每个原型创建一个新对象,然后您可以将方法放在该对象上。Prototype委派将确保属性查找沿着Prototype链进行。

问题在于如何在以下行中使用Stage的Prototype:

ParallelStage.prototype = Stage.prototype
ParallelStage.prototype
现在只是指向
Stage.prototype
的指针。修改时,将使用阶段原型替换所有对象的父函数

出现您的具体问题是因为Serial.js在Stage.js和Parallel.js之后执行;它是对
Stage的更改。prototype
是最后一个,对
Stage
SerialStage
ParallelStage
类型的任何对象都有效

从父级继承原型的正确方法(或正确方法之一)是使用以下方法:

Child.prototype = Object.create(Parent.prototype)
更改您的代码以使用此模式,您应该获得您所追求的行为

ParallelStage.prototype = Stage.prototype
Child.prototype = Object.create(Parent.prototype)