2016-01-28 2 views
4

У меня есть базовый класс, как:неожиданные результаты с JS прототипа наследования

Stage.js:

function Stage(name) { 
    this.my_name = name; 
} 

Stage.prototype.name = function() { 
    return this.my_name; 
} 

module.exports = Stage; 

Parallel:

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 и наследование прототипов. Может кто-то подсказывает мне, чего я здесь не хватает? Я ожидал его, чтобы показать выполнение этапа параллельно не серийные ...

ответ

0

Для правильного наследования прототипа вы должны использовать

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); 
+0

Отлично! Благодаря! – RedBullet

0

Вы устанавливаете прототип как 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 и ряд других решений, чтобы создать копию прототипа объект, чтобы не переписывать его свойства каждый раз, но это sorta поражает цель наследования его в первую очередь.

0

Когда вы делаете:

SerialStage.prototype = Stage.prototype; 

вы не создаете копию базового прототипа - что это и как и любое другое задание, он указывает на существующий объект. Поэтому вместо того, чтобы давать уникальные прототипы ParallelStage и SerialStage, вы повторно используете один и тот же прототип для обоих конструкторов. И когда вы назначили метод execute, вы перезаписали существующий один раз, а не создали новый.

Быстро и легко исправить было бы сделать это вместо:

ParallelStage.prototype = new Stage(); 

и

SerialStage.prototype = new Stage(); 

Это создает новый объект для каждого прототипа, который вы можете поставить методы на. Делегирование прототипов гарантирует, что поиск свойств будет расти в цепочке прототипов.

0

Проблема заключается в том, как вы используете прототип этапе в следующей строке:

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) 

Изменить код, чтобы использовать этот шаблон, и вы должны получить информацию о поведении вы» повторно после.