Javascript 静态方法继承
Javascript static method inheritance
我想创建一个Javascript类/对象,允许我有各种方法:
模型类
-
Model.all()
» 静态方法 -
Model.find()
» 静态方法 -
Model delete()
» 实例方法 -
Model save()
» 实例方法 -
Model.create()
» 返回新模型实例的静态
对于静态方法,我可以使用以下命令定义它们:
Model.staticMethod(){ method }
而例如方法最好使用:
function Model(){
this.instanceMethod = function(){}
}
,然后创建一个新实例
还是使用原型?
var m = function Model(){
}
m.prototype.method() = function() {
}
现在假设我想创建一个基于 Model 的新类,如何不仅继承它的原型,还继承它的静态方法?
编辑:
为了避免混淆,这或多或少是我想创建的:
http://activejs.org/activerecord/index.html 和 http://activejs.org/activerecord/ActiveRecord/Model/index.html
我可以使用类似的东西定义一个新模型
var User = ActiveRecord.create({
username: '',
password: '',
post_count: 0,
profile: ''
}
然后创建实例
var jessica = User.create({
username: "Jessica",
password: "rabbit"
});
使用实例方法,例如
jessica.save();
还有类方法:
User.findByUsername('Jessica');
function 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();
};
使用 var InheritedModel = Object.create( Model );
时,它还继承了静态方法。
var InheritedModel = Object.create( Model );
!!InheritedModel.all // true
但是,你不能做new InheritedModel()
,因为它不是一个函数,使用Object.create( InheritedModel )
不会给你实例方法。
如果要使用 new
实例化继承的类,则需要以下内容:
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 ];
} );
编辑:看到您的编辑后,这是我推荐您的解决方案:
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() {}
注释代码是伪代码。您可以通过以下方式实现相同的目标:
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;
}
};
用法
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');
你可以扩展对象的原型,向 Object.prototype 添加一个"extends"方法。这样,您将拥有一个看起来像java的继承方法。
(将"extends"属性定义为不可枚举很重要,否则会破坏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;
}
});
通过这样做可以轻松地将一个类继承到另一个类之后:
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 */
};
继承模型将继承模型的所有实例方法和所有静态方法。
例:
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 */
我认为这是最好的解决方案。
怎么样,你有私有和公共方法:
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();
};
- 无法理解JavaScript中的静态方法
- 从构造函数es6调用静态方法
- 如何理解“当类实例化时,JavaScript静态方法也是不可调用的”
- Javascript:如何声明非全局静态方法
- 定义的静态方法未定义
- 使用 Babel 转译器导入类并调用带有 ES6 模块的静态方法
- 从常规ES6类方法中调用静态方法
- 在Javascript中,如何继承和扩展正在继承的方法
- React中的静态方法
- React中的单元测试非静态方法
- JavaScript中的静态方法
- 可以't从客户端应用程序引用插件中定义的静态方法
- 静态方法中的Javascript“this”
- 如何在 ReactJS 中限制静态方法
- Javascript原型继承私有方法
- Javascript 静态方法继承
- 如何继承静态方法
- Javascript继承静态和实例方法/属性
- 继承方法(原型)和静态方法(表达式)的区别是什么?
- Node.js中可继承的静态方法