#javascript #inheritance
#javascript #наследование
Вопрос:
Я пытаюсь достичь 2 уровней наследования в javascript без каких-либо рамок.
**Class --> Model --> ListModel**
в идеале код должен выглядеть так
var Class = function(){}
var Model = new Class;
var ListModel = new Model;
после реализации я мог бы предложить следующее решение, которое плохо пахнет.
var Class = function(){
klass = function(){};
klass.extend = function(){ console.log("extend")}
klass.prototype.include = function(){ console.log("include") };
return klass
}
var Model = function(parent){
var model = function(){
}
if(parent){
for(var i in parent){
model[i] = parent[i];
}
for(var i in parent.prototype){
model.prototype[i] = parent.prototype[i];
}
}
model.record = [1,2];
model.prototype.generateId = function(){ console.log("genrate ID")};
return model
}
var ListModel = function(parent){
if(parent){
for(var i in parent){
ListModel[i] = parent[i];
}
for(var i in parent.prototype){
ListModel.prototype[i] = parent.prototype[i];
}
}
}
var class = new Class()
var model = new Model(class)
var l = new ListModel(model)
может ли кто-нибудь помочь мне сделать это лучше?
Комментарии:
1. вы можете использовать setPrototypeOf (и polyfills) вместо циклов или просто установить Model.prototype=class , но вы смешиваете метафоры, используя «новый экземпляр» вместо «нового конструктора»…
Ответ №1:
Обычно я использую функцию, вызываемую defclass
для определения «классов» (фактически конструкторов), которые не наследуются ни от чего другого:
function defclass(prototype) {
var constructor = prototype.constructor;
constructor.prototype = prototype;
return constructor;
}
С помощью defclass
вы можете создавать классы следующим образом:
var Model = defclass({
constructor: function (...) {
// init code
},
someMethod: function (...) {
// do something
}
});
Однако, когда дело доходит до наследования, вам нужно что-то большее. Итак, я написал свою собственную extend
функцию:
function extend(constructor, keys) {
var supertype = keys.super = constructor.prototype;
var prototype = Object.create(supertype);
for (var key in keys) prototype[key] = keys[key];
return defclass(prototype);
}
Используя extend
, теперь вы можете наследовать от других классов следующим образом:
var ListModel = extend(Model, {
constructor: function (...) {
// init code
},
someMethod: function (...) {
// override default implementation
// use `this.super` to gain access to overridden methods
},
someOtherMethod: function (..) {
// do something else
}
});
Просто, не правда ли?