原文:http://javascriptmvc.com/docs.html#&who=jQuery.Class
翻译:刘贵学([email protected])
Class库能在Javascript中模拟继承,使用class可进行面向对象编程,这和jQuery函数式编程是有区别的。Class的实现基于John Resig的《Simple Class》继承库,除了实现继承,Class库还包括一些重要的特征:
在学习class库之前,我们需要先了解class的静态与原型属性;
//STATIC MyClass.staticProperty //共享属性 //PROTOTYPE myclass = new MyClass() myclass.prototypeMethod() //实例方法
一个静态的(或类的)属性属于类的构造函数,可以被此类的所有实例共享;原型属性则只属于各自实例。
下面我们将创建一个名为的类(方便自省),并加入一些静态与原型成员。每当Monster 的实例被创建是,静态(属性)计数器将增加。
$.Class.extend('Monster',
/* @static */
{
count: 0
},
/* @prototype */
{
init: function( name ) {
// saves name on the monster instance
this.name = name;
// sets the health
this.health = 10;
// increments count
this.Class.count++;
},
eat: function( smallChildren ){
this.health += smallChildren;
},
fight: function() {
this.health -= 2;
}
});
hydra = new Monster('hydra');
dragon = new Monster('dragon');
hydra.name // -> hydra
Monster.count // -> 2
Monster.shortName // -> 'Monster'
hydra.eat(2); // health = 12
dragon.fight(); // health = 8
注意:当一个Monster新的实例创建时,原型函数init将自动执行。
当继承一个类时,所有静态与原型属性在子类中都是可用。如果您想覆盖(overwrite)一个函数,可以通过this._super调用基类。让我们创建一个类,SeaMonster 吃的(eat)更少,但战斗力(fight)更强。
Monster.extend("SeaMonster",{
eat: function( smallChildren ) {
this._super(smallChildren / 2);
},
fight: function() {
this.health -= 1;
}
});
lockNess = new SeaMonster('Lock Ness');
lockNess.eat(4); //health = 12
lockNess.fight(); //health = 11
您也可以通过如下方法继承静态属性:
$.Class.extend("First",
{
staticMethod: function() { return 1;}
},{})
First.extend("Second",{
staticMethod: function() { return this._super()+1;}
},{})
Second.staticMethod() // -> 2
命名空间
命名空间是个很棒的想法,我们鼓励您在代码中使用命名空间,它能使您的代码可轻松移植到其他应用(避免命名冲突)。创建一个带命名空间的类非常容易:
$.Class.extend("MyNamespace.MyClass",{},{});
new MyNamespace.MyClass()
通常在创建类时,类名有助于一些确定性 (determine) 的功能。Ruby on Rails的ActiveRecord的ORM类就是非常典型的例子。不过Javascript还不支持指定对象的名字,所以需要开发者提供一个名称,Class库将接受到的这个字符串定为类名。
$.Class.extend("MyOrg.MyClass",{},{})
MyOrg.MyClass.shortName //-> 'MyClass'
MyOrg.MyClass.fullName //-> 'MyOrg.MyClass'
fullName(带命名空间)与shortName(不带命名空间)将作为类的静态属性加入。
Class库提供静态与原型初始化函数,即setup与init。Setup 比init先调用,可以用于规范化init的参数。
提示:通常情况下,您不需要setup函数,多用init替代;相反,setup函数适用于init调用之前的对类进行一些复杂的预处理。
$.Class.extend("MyClass",
{
setup: function() {} //static setup
init: function() {} //static constructor
},
{
setup: function() {} //prototype setup
init: function() {} //prototype constructor
})
Setup函数在init函数调用之前, Static setup functions are passed the base class followed by arguments passed to the extend function. Prototype static functions are passed the Class constructor function arguments.
如果Setup函数返回一个数组,则此数组将作为init函数的参数,这样setup函数便可规范传入init的参数,这也是setup最常用的用法。
接下来,将讲述如何使用jQuery.Controller.setup 来保障init的参数为HTML元素,但不能扩展init的参数。
$.Class.extend("jQuery.Controller",{
...
},{
setup: function( el, options ) {
...
return [$(el),
$.extend(true,
this.Class.defaults,
options || {} ) ]
}
})
Init函数的调用在setup函数之后,通常情况下,他们会收到来自setup函数同样的参数。Foo类的init函数的调用示例如下:
$.Class.Extend("Foo", {
init: function( arg1, arg2, arg3 ) {
this.sum = arg1+arg2+arg3;
}
})
var foo = new Foo(1,2,3);
foo.sum //-> 6
类似于jQuery的代理方法,类会先提供一个回调函数,其返回会回调给此给类或实例的函数。
下面的例子则使用了 this.callback来确保在show中this.name可用:
$.Class.extend("Todo",{
init: function( name ) { this.name = name }
get: function() {
$.get("/stuff",this.callback('show'))
},
show: function( txt ) {
alert(this.name+txt)
}
})
new Todo("Trash").get()
回调函数在静态与原型函数中都可用。