Class提供相当继承的功能。使用Class就可以让我们结合面对过程和面对对象编程开发。 除了原型继承之外,它还包含了一些重要的特性:
1、静态继承 2、内省 3、命名空间 4、Setup和Init方法 5、容易创建回调函数
静态 V 原型
在学习Class之前,理解一个Class的Static和Prototype属性的不同。
//STATIC MyClass.staticProperty //shared property //PROTOTYPE myclass = new MyClass() myclass.prototypeMethod() //instance method
一个静态属性是在类的构造函数中,它共享给所有类的实例。原型属性只能在类实例中使用。
一个最原始的类
下面我们创建一个Monster类用一个名字,静态和原型成员。每次创建一个Moster类实例,静态成员count递增1.
$.Class('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.constructor.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
注意每个新Moster类实例创建时,原型init方法都会被调用。
继承
当一个类被扩展时,所有静态和原型属性都继承到新类中。如果子类重写父类的方法,那么你可以通过调用this._super来调用父类的方法。 下面让我们来创建一个海怪物类,海怪物有吃小孩的能力,但是不吃多数的强大的战士。
Monster("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("First", { staticMethod: function() { return 1;} },{}) First("Second",{ staticMethod: function() { return this._super()+1;} },{}) Second.staticMethod() // -> 2
命名空间
命名空间是一个好概念!我们鼓励大家在你的所有代码中使用命名空间。 命名空间的好处:可以把代码移动到其它工程,而且没有什么问题。 创建一个命名空间类是很容易的:
$.Class("MyNamespace.MyClass",{},{}); new MyNamespace.MyClass()
内省
常常,类名最好起与相关功能的名称,这样有助于我们知道该类有什么作用。然而,JavaScript无法决定一个对象的名称,所以开发人员 必须给类起名。类定位就是通过给类一个字符串名称来通话的。
$.Class("MyOrg.MyClass",{},{}) MyOrg.MyClass.shortName //-> 'MyClass' MyOrg.MyClass.fullName //-> 'MyOrg.MyClass'
全名和简名都是添加到类的静态属性上。
Setup和init方法
Class支持静态和原型初始化方法。这里有2个初始化方法-setup和init。Setup在init之前执行,且可以使用正规化init的参数。
说明:通常,在类中不需要setup方法。使用init代替它。保留setup方法,当我们需要处理更加复杂再去调用。
$.Class("MyClass", { setup: function() {} //static setup init: function() {} //static constructor }, { setup: function() {} //prototype setup init: function() {} //prototype constructor })
Setup
Setup函数是在Init函数前调用。静态Setup函数是允许通原始类参数来处理的扩展函数。原型静态方法是处理类构造函数的参数。 如果一个Setup函数返回一个数组,这个数组可以当成参数在Init函数中使用。所以,Setup能够把处理完正规的参数传到init构造函数。 这些也是我们需要执行Setup函数代码的一个好处。 下面我们看看jQuery.Controller.setup中如何确定init函数调用的参数都是一个HTML元素和合并的选项同。
$.Class("jQuery.Controller",{ ... },{ setup: function( el, options ) { ... return [$(el), $.extend(true, this.Class.defaults, options || {} ) ] } })
一般情况,我们是不需要创建和重写Setup函数的。
Init
Init函数是在Setup后调用。通常,Init函数接收到和前台Setup函数一样的参数。 下面就是一个Foo类Init方法被调用的例子:
$.Class("Foo", { init: function( arg1, arg2, arg3 ) { this.sum = arg1+arg2+arg3; } }) var foo = new Foo(1,2,3); foo.sum //-> 6
代理
类似于Juqery的代理方法,Class提供了一个proxy函数,它返回一个回调函数,这个函数一般是设置到类中或者类的实例。 下面例子使用this.proxy来确定this.name在show中是否有效。
$.Class("Todo",{ init: function( name ) { this.name = name }, get: function() { $.get("/stuff",this.proxy('show')) }, show: function( txt ) { alert(this.name+txt) } }) new Todo("Trash").get()
Class还提供了几个有用的静态方法:
1、extend 继承
// with className, static and prototype functions $.Class('Task',{ STATIC },{ PROTOTYPE }) // with just classname and prototype functions $.Class('Task',{ PROTOTYPE }) // with just a className $.Class('Task')
2、fullName 类全名
$.Class("MyOrg.MyClass",{},{}) MyOrg.MyClass.shortName //-> 'MyClass' MyOrg.MyClass.fullName //-> 'MyOrg.MyClass'
3、namespace 类的命名空间
$.Class("MyOrg.MyClass",{},{}) MyOrg.MyClass.namespace //-> MyOrg
4、newInstance 类创建实例的方法,它对于我们为实例添加任意参数很有用。
$.Class("MyClass",{},{}) var mc = MyClass.newInstance.apply(null, new Array(parseInt(Math.random()*10,10))
5、shortName 类简名
$.Class("MyOrg.MyClass",{},{}) MyOrg.MyClass.shortName //-> 'MyClass' MyOrg.MyClass.fullName //-> 'MyOrg.MyClass'