2015-07-17 3 views
0

Я недавно был преобразован из C# er в Javascripter. У меня есть фундаментальный вопрос о том, как я должен разрабатывать свои «классы» в отношении общих свойств/методов.Javascript: правильный способ наследования свойств/методов

Ниже я хочу иметь «id» как общее свойство наряду с методами начала и остановки. Конечно. «id» будет отличаться от экземпляров MyDerivedClass. Может быть MyOtherDerivedClass, который должен быть наследован от MyBaseClass, поэтому хотел, чтобы этот «id» был общим свойством в базе. Может быть, мое мышление - это то, что мне нужно, чтобы получить право, пожалуйста, дайте мне знать, как я мог бы переделать это так, как это делается в Javascript.

var MyBaseClass = function(id){ 
MyBaseClass.prototype.id = id;  
MyBaseClass.prototype.start = function(){ 
    console.log('Starting item %s', this.id); 
    //...// 
    console.log('Started item %s', this.id); 
}; 

MyBaseClass.prototype.stop = function(){ 
    console.log('Stopping item %s', this.id); 
    //...// 
    console.log('Stopped item %s', this.id); 
}; 
}; 

var MyDerivedClass = function(id){  
    MyDerivedClass.prototype.connected = false; 
    MyDerivedClass.prototype.id = id; //????? 
}; 

inherit(MyDerivedClass, jsDialTone.common.items.DynamicItem); 

// This is the inherit method 
var inherit = function(child, base){ 
var Dummy = function(){}; 
Dummy.prototype = base.prototype; 
child.prototype = new Dummy(); 
child.prototype.constructor = child; 
}; 

var d1 = new MyDerivedClass('D1'); 
expect(d1.id).toBe('D1'); // passes 
var d2 = new MyDerivedClass('D2'); 
expect(d1.id).toBe('D1'); // fails, since I modified the prototype. 

ответ

2

Использование d2.id = 'D2' (но на самом деле this.id = id в конструкторе); и сделать то же самое для флага connected.

Значение идентификатора не разделяют между экземплярами и является для них не фитинга для использования общей собственности на [[Prototype]].

В общем, [[Prototype]] объекты должны не быть изменены в соответствующих конструктора-функциях, потому что обычно не имеет смысла: это сродни установки статического (или «общие») переменные в C# или конструктор Java.

+0

Я предполагаю, что это произошло из нескольких чтений, с которыми я столкнулся, вероятно, я не получил их правильно. Но скажите, является ли этот код частью какой-либо библиотеки и пользователь этой библиотеки, var instance = Object.create (MyDerivedClass.prototype), экземпляр должен иметь свойство, называемое id или связанное ya? Или они должны фактически делать Object.create (MyDerivedClass).Я имею в виду, я думал: «id» и «connected» были похожими на «общие» для всех экземпляров, но их значения различны, но все экземпляры имеют «id». Следовательно, прототипом было место для этого. – theraneman

+0

Использование прототипа (что бы это ни было, не обязательно F.prototype) с Object.create является правильным. Обычно не имеет смысла передавать функцию непосредственно Object.created, поскольку обычно не выполняется 'MyDerviedClass.thisIsToBeAPrototypeProperty = ..'. Object.create, возможно, более прототип-OO-ish, чем установка свойства прототипа функции, вызываемой с помощью 'new', но оказывает такое же влияние на [[prototype]] вновь созданного объекта. – user2864740

+0

'var MyBaseClass = function (id) { this.id = id; }; ' ' var MyDerivedClass = function (id) { this.connected = false; MyBaseClass.call (this, id); }; ' ' унаследуют (MyDerivedClass, jsDialTone.common.items.DynamicItem); ' Если это будет право исправить тогда? – theraneman

1

Вышеупомянутый ответ должен решить вашу проблему, вот немного больше.

function MyBaseClass(id) { 
    this.id = id; 
} 

MyBaseClass.prototype.start = function() { 
    console.log('Starting item ', this.id); 
    //...// 
    console.log('Started item ', this.id); 
}; 

MyBaseClass.prototype.stop = function() { 
    console.log('Stopping item ', this.id); 
    //...// 
    console.log('Stopped item ', this.id);  
}; 

function MyDerivedClass(id) { 
    MyBaseClass.call(this, id); 
} 

MyDerivedClass.prototype = Object.create(MyBaseClass.prototype); 


var base = new MyBaseClass(1); 

var derived = new MyDerivedClass(2); 

base.start(); 

derived.start(); 

Это должно напечатать в консоли:

Starting item 1

Started item 1

Starting item 2

Started item 2

  • Вы создадите класс MyBaseClass, а затем установите методы на его прототипе.
  • Затем вы создадите MyDerivedClass, который использует метод .call(), который будет запускать функцию MyBaseClass, но он будет явно указывать this с первым аргументом.
  • Затем вы установите прототип MyDerivedClass прототипу MyBaseClass с Object.create().

Проверить эти ссылки для большего количества ссылок:

Prototypal inheritance

The .call() method

JavaScript странно.

Смежные вопросы