原文:http://javascriptmvc.com/docs.html#&who=jQuery.Class
翻譯:劉貴學(liuguixue@gmail.com)
Class庫能在Javascript中類比繼承,使用class可進行物件導向編程,這和jQuery函數式編程是有區別的。Class的實現基於John Resig的《Simple Class》繼承庫,除了實現繼承,Class庫還包括一些重要的特徵:
- 靜態繼承
- 自省
- 命名空間
- Setup與Init方法
- 易建立的回呼函數
靜態(STATIC)與原型(PROTOTYPE)
在學習class庫之前,我們需要先瞭解class的靜態與原型屬性;
//STATIC<br />MyClass.staticProperty //共用屬性</p><p>//PROTOTYPE<br />myclass = new MyClass()<br />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 // -> hydraMonster.count // -> 2Monster.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 = 12lockNess.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
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
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()
回呼函數在靜態與原型函數中都可用。