Matteo Pagliazzi Matteo Pagliazzi - 6 months ago 14
Javascript Question

Javascript static method intheritance

I want to create a javascript class/object that allow me to have various method:

Model class


  • Model.all()
    » static method

  • Model.find()
    » static method

  • Model delete()
    » instance method

  • Model save()
    » instance method

  • Model.create()
    » static that returns a new Model instance



For static method I can define them using:

Model.staticMethod(){ method }


while for instance method is better to use:

function Model(){
this.instanceMethod = function(){}
}


and then create a new instance

or using prototype?

var m = function Model(){

}

m.prototype.method() = function(){

}





Now let's say that I want to create a new class based on Model, how to inherit not only its prototypes but also its static methods?

EDIT:

to avoid confusion this is more or less what I want to create:

http://activejs.org/activerecord/index.html and http://activejs.org/activerecord/ActiveRecord/Model/index.html

where I can define a new model using something like that

var User = ActiveRecord.create({
username: '',
password: '',
post_count: 0,
profile: ''
}


then create an instance

var jessica = User.create({
username: "Jessica",
password: "rabbit"
});


use instance methods like

jessica.save();


but also class methods:

User.findByUsername('Jessica');

Answer

Commented code is pseudo code. You can achieve the same by:

var modelInstanceMethods = {

    save: function() {
        /*
        insert into this.tableName blabla
        */
    },

    'delete': function() {
        /*
        delete from this.tableName blabla
        */
    }
};

var modelStatics = {

    create: function(obj) {
        return new this(obj);
    },

    all: function() {
        /*
        return select * from this.tableName.map( function( values ) {
            return new this(values);
        },this);
        */
    },

    find: function(id) {
        /*
        select * from this.tableName where id = id
        return new this(columnValues);
        */
    }


};

var ActiveRecord = {
    create: function( tableName, fields, methods ) {

        function Model( obj ) {
            this.tableName = tableName;
            this.fields = {};
            if( fields ) {
                for( var field in fields ) {
                    this.fields[field] = fields[field];
                }
            }

            if( obj ) {
                for( var field in obj ) {
                    this.fields[field] = obj[field];
                }       
            }
        }

        Model.tableName = tableName;
        Model.prototype = Object.create(modelInstanceMethods);
        Model.prototype.constructor = Model;

        for( var key in modelStatics ) {
            Model[key] = modelStatics[key];
        }

        if( methods ) {
            for( var key in methods ) {
                Model.prototype[key] = methods[key];
            }   
        }

        return Model;
    }
};

Usage

var User = ActiveRecord.create('users',
    /* fields and their default values */
{
    id: 0,
    username: '',
    password: '',
    post_count: 0,
    profile: ''
}, {
    /*instance methods */
    setPassword: function(password) {
        this.fields.password = password;
    }
});

/*You can define static methods like this */

User.findByUsername = function(username) {
    /*select from this.tableName where userName = username
               return new this(columnValues) blabla
             */
};

var jessica = User.create( {
    username: "Jessica",
    password: "rabbit"
});

jessica.save();

User.findByUsername('Jessica');