2-уровневое наследование в javascript

#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
    }
});
 

Просто, не правда ли?