admin管理员组文章数量:1317906
I want to create a Javascript class/object that allow me to have various method:
Model class
Model.all()
» static methodModel.find()
» static methodModel delete()
» instance methodModel save()
» instance methodModel.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:
.html and .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');
I want to create a Javascript class/object that allow me to have various method:
Model class
Model.all()
» static methodModel.find()
» static methodModel delete()
» instance methodModel save()
» instance methodModel.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/activerecord/index.html and http://activejs/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');
Share
Improve this question
edited Jun 7, 2016 at 20:36
marc_s
756k184 gold badges1.4k silver badges1.5k bronze badges
asked Jun 19, 2012 at 8:57
Matteo PagliazziMatteo Pagliazzi
5,27012 gold badges51 silver badges85 bronze badges
9
-
Yes you should use
prototype
, otherwise you create new function objects for every object you instantiate. – Esailija Commented Jun 19, 2012 at 9:05 - possible duplicate of Use of 'prototype' vs. 'this' in Javascript? – Felix Kling Commented Jun 19, 2012 at 9:11
-
Regarding your last question, you probably have to iterate over the methods you added to
Model
and assign them to the new class as well. – Felix Kling Commented Jun 19, 2012 at 9:14 - so not something referred to the whole class? because to me seems a bit strange to do var a = new Model() and then a.all since a represents a single istance it shouldn't be used to get all the models from the server (all() should do this) – Matteo Pagliazzi Commented Jun 19, 2012 at 9:16
-
2
There are no real static methods. Everything is an object and everything can have properties. If you assign
Model.all = ...
, then later you callModel.all()
.var a = new Model(); a.all()
would not even work. Or maybe you misunderstood my ment and I yours. – Felix Kling Commented Jun 19, 2012 at 9:27
4 Answers
Reset to default 5function Model() {}
// Methods in the instantiated object
Model.prototype = {
constructor: Model,
// Note that "delete" is a reserved word, so we need quotes
'delete': function() {},
save: function() {}
};
// Static methods
Model.all = function() {};
Model.find = function() {};
Model.create = function() {
return new Model();
// To be more generic, you can also:
return new this();
};
When you use var InheritedModel = Object.create( Model );
, it also inherits the static methods.
var InheritedModel = Object.create( Model );
!!InheritedModel.all // true
However, you can't do new InheritedModel()
, because it's not a function, and using Object.create( InheritedModel )
won't give you the instance methods.
If you want to instantiate the inherited class using new
, you need the following:
function InheritedModel() {}
InheritedModel.prototype = Object.create( Model.prototype );
// Copy all the static methods in the InheritedModel object
Object.keys( Model ).forEach( function( key ) {
InheritedModel[ key ] = Model[ key ];
} );
Edit: after seeing your edit, here is the solution I'd remend you:
function ActiveRecord( type, args ) {
if ( type = 'users' ) {
return new this.users();
}
}
// Static method on ActiveRecord
ActiveRecord.create = function( type, args ) {
return new ActiveRecord( type, args );
};
ActiveRecord.prototype = {
constructor: ActiveRecord,
// Instance method on ActiveRecord, you won't need it,
// but your constructor does
users: function( args ) {}
};
var Users = ActiveRecord.prototype.users;
Users.prototype = {
constructor: Users,
// Instance method on User's instance
save: function() {}
}
// Static method on User
Users.create = function() {}
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');
You can extend the Object's prototype adding an "extends" method to Object.prototype. This way you will have an inherithance method that look like java.
(it's important to define the "extends" property as not enumerable otherwise it will break jQuery)
Object.defineProperty(Object.prototype, "extends", {
"enumerable": false,
"value" : function(constructor) {
/*Inheriting enumerable statick method and paramether
from the super class */
Object.keys( constructor ).forEach( function(key) {
this[key]= constructor[key];
}.bind(this));
/*Classic Javascript inheritance*/
this.prototype= Object.create( constructor.prototype, {
"constructor": {
"value": this,
"configurable": true
}
});
this.__super__= constructor;
}
});
After you can easily inherit one class by an other by doing so:
InheritedModel.extends(Model);
function InheritedModel(params){
this.constructor.__super__.call(this, params);
/* Or directly :
Model.call(this,param);
*/
/*Code specific to InheritedModel constructor */
}
/*To overload method from the super class:*/
InheritedModel.prototype.foo= function(params){
var out= this.constructor.__super__.prototype.foo.call(this,params);
/* Or
var out= Model.prototype.foo.call(this,param);
*/
/* code */
};
InheritedModel will inherit of all the instance method and all static method from model.
Example:
function Model() {
this.inheritedClassName= "Model";
};
Model.inheritedClassName= "Model";
Model.getClassName = function() {
return this.name;
};
Model.prototype.getClassName = function() {
return this.constructor.name;
};
InheritedModel.extends(Model);
function InheritedModel() {
Model.call(this);
}
console.log(InheritedModel.inheritedClassName);/* Model */
console.log(InheritedModel.getClassName());/* InheritedModel */
var inheritedModel= new InheritedModel();
console.log(inheritedModel.inheritedClassName);/* Model */
console.log(inheritedModel.getClassName());/* InheritedModel */
I think this is the best solution.
what about this, you have private and public methods:
function Model() {
var privateMethods = {
private1: function() {},
private2: function() {},
private3: function() {},
};
var publicMethods = {
method1: function() {},
method2: function() {
//call a private method...
privateMethods.private1();
}
};
return publicMethods;
}
// Static methods
Model.all = function() {};
Model.find = function() {};
Model.create = function() {
return new Model();
};
本文标签: oopJavascript static method inheritanceStack Overflow
版权声明:本文标题:oop - Javascript static method inheritance - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742009089a2412550.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论