2013-03-08 3 views
2

У меня проблема с узлом node.js с javascript oop. Я создал класс, используя другой класс.javascript и node.js: oop

var base = function (name) {  
    this.Rows = new Array();  
}; 

var top = function (name) { 
    this.name = name; 
}; 

top.prototype = new base(); 

var myClass = new top(""); 
myClass.Rows.push("a"); 
console.log(myClass.Rows); 
var myClass2 = new top("test"); 
myClass2.Rows.push("b"); 
console.log(myClass2.Rows); 

Этот код возвращает следующие результаты;

[ 'a' ] 
[ 'a', 'b' ] 

но мне не нужно искать по алгоритму в результате этого кода?

[ 'a' ] 
[ 'b' ] 

Благодарим за помощь.

Решение: я решил эту проблему. рефакторинг;

var base = function (name) { 
    this.Rows = new Array(); 
} 

var top = function(name) { 
    top.prototype.constructor.call(this, name); 
    this.name = name; 
} 

top.prototype = Object.create(new base()); 

благодарит всех.

+0

Это хорошее место для начала: http://www.2ality.com/2012/01/js-inheritance-by-example.html –

ответ

6

Так работает прототипическое наследование JavaScript.

Это кажется довольно запутанным для новичков в языке :)

myClass Оба объекта и myClass2 имеют один и тот же прототип (набор в top.prototype = new base();)

Это означает, что при обращении к их Rows собственности, поскольку ни один из них имеет они получают доступ к одному из своих прототипов. Поскольку они одинаковы для обоих, оба они действуют на одном и том же объекте. Если добавить строку console.log(myClass2.Rows); в конце кода было бы также выход [ 'a', 'b' ]

Прототипическая наследование кажется, запутать начинающих, так как в классических языках, если класс A расширяет класс B тогда все свойства A «s копируются в B - это это не так в JavaScript.

Вы можете выполнить ту же функциональность, если вы реорганизовывать код к следующему:

var base = function() {  

}; 

base.prototype.getRows = function(){ 
    return this.rows; 
} 

var top = function (name) { 
    this.name = name; 
    this.rows= [];  
}; 

top.prototype = new base(); 

var myClass = new top(""); 
myClass.getRows().push("a"); 
console.log(myClass.getRows()); 
var myClass2 = new top("test"); 
myClass2.getRows().push("b"); 
console.log(myClass2.getRows()); 

Это производить «классический» результат вы ожидаете.

Однако прототипная модель JavaScript больше ориентирована на обмен функциональность. Я бы, вероятно, реорганизовал ваш код:

var myClass = {Rows:[]},myClass2 = {Rows:[]}; 
+0

Я хочу, чтобы каждая строка в результирующем наборе нового объекта создавалась. так что правильный результат ['a'] ['b'] Я хочу быть. var base = function (name) { this.Rows = new Array(); }; // var top = function (name) { // This.name = name; //}; // top.prototype = new base(); var myClass = новая база (""); myClass.Rows.push ("a"); console.log (myClass.Rows); var myClass2 = новая база (""); myClass2.Rows.push ("b"); console.log (myClass2.Rows); Код таким образом является правильным результатом. результат неверен в другом классе, класс был сгенерирован. –

+0

@KiPSOFT Я думаю, что ваша проблема требует немного понимания того, как работает JavaScript oop, если вы хотите более подробно обсудить, как это работает, вы можете посетить http://chat.stackoverflow.com/rooms/ 17/javascript, где я хотел бы объяснить, как работает проект OOP JavaScript :) –

+1

:) Теперь я понимаю лучше. вы определяете верхний класс. Итак, я хотел создать более одного класса. Я использую подкласс для каждого класса, для которого нужно переопределить свойство Rows. –

2

Да, прототипы являются общими. Я думаю, что вы хотели этот тип наследования:

var base = function (name) { 
    this.Rows = new Array(); 
}; 

var top = function (name) { 
    base.call(this,name); // this replaces your prototype 
    this.name = name; 
}; 

var myClass = new top(""); 
myClass.Rows.push("a"); 
console.log(myClass.Rows); 
var myClass2 = new top("test"); 
myClass2.Rows.push("b"); 
console.log(myClass2.Rows); 

вызова будет вызывать функцию, как если бы это был метод, поэтому он будет создан объект как base, то изменить его с определенными свойствами. Как отметил nrabinowitz в комментариях, это не наследует никаких прототипов.

Также мое первоначальное предложение, которое я очень люблю, но это не имеет преимуществ по сравнению с выше:

var top = function (name) { 
    this.super=base; // these two lines replace your prototype 
    this.super(name); 
    this.name = name; 
}; 

метод делает «базу» в функции члена, то это называет. Он настроит «верх» как новый «базовый» объект, а затем настроит его.Я выбрал «super» как имя переменной, потому что он похож на стиль Objective C.

+0

@ Downvoter: помогите объяснить? – Dave

+0

Это интересный подход (хотя примечание, что оно не поддерживает прототипное наследование «базовых» методов, просто настройка конструктора). Более распространенной идиомой JS может быть использование 'base.call (this)' или 'base.apply (this, arguments)' (если вам нужно иметь общие аргументы между конструкторами). – nrabinowitz

+0

Я не думал о '.call', и это, конечно, было бы лучше (быстрее, менее переменное загрязнение). Я обновлю его, хотя, честно говоря, мне очень нравится «супер» стиль! – Dave