prototype.js的擴展1.1版( 2006年11月)
即extend.js
Extend讓您在JavaScript的應用中使用傳統的單類繼承(類似java語言). 它還提供很多先進的功能,如運行時類的重定義,反射和修改.
你可以下載1.1版(最新)在這裏
http://www.ivy.fr/js/extend/extend.js
一個測試套件
http://www.ivy.fr/js/extend/extend-test.html
有什麼創新的? * 1.1 ( 2006年11月) -Extend.js不依賴於Prototype.js,所以你可以將它用於任何項目. 它還包括一個新supercall (name, ... )方法,實現調用父類中定義的某一方法. 這等於super.name……
JavaScript語言存在的問題:因爲它是基於原型的,所以沒有提供一個默認的方式來處理繼承. 但是有可能在JavaScript原型系統基礎上做成傳統OO式的繼承形式.
著名的prototype.js提供了一個很基本的方法來創建類,如下:
var MyClass = Class.create()
var MyClass.prototype = {
attribute:value,
...
initialize:function(arg1,arg2,...) {
}
method:function(arg1,arg2,...) {
...
},
...
}
一個對象就可以輕易實例化,例如
var instance = new MyClass()
但有沒有簡單的方法實現MyClass的子類定義.
類似extendclass extendclassfurther的擴展提供了extend或者subclass設法解決這一問題,允許對一個存在的class繼承. 這些擴展提供了一種機制,從父類調用方法(相當於super的語法) .
然而,這兩個擴展沒有一個靈活而可靠的super當量,造成的結果是高級JavaScript的應用軟件開發非常困難.
此外,這兩種擴展仍然不允許對類的元信息進行規範制定(如class name,methods,parent class等) , 這纔是調試和反射開發中真正有用的要素.
解決辦法:我們建議設立一個比較簡單的OO層,由兩部分構成組成:
*每個類增加額外的方法和屬性,使得可以對類直接存儲、操作元信息
*爲每個實例化的對象提供本身和父類的存取訪問器.
*提供一個簡單的方式來獲取和調用父類中定義的方法
類中的對象
className 字符串 類的名字(可未定義)
parentClass 類對象 是父類的引用(可未定義
constructor() 返回 類中定義的構造器
method(n) 根據名字返回定義的方法,或者拋出一個異常.
method(n,F) 根據名字用一個已有的函數來定義一個方法,也可以用來更新子類如果f是無效的方法是移除.
methods 字典 這個類中定義的方法.很少會用
inherited 字典 映射到類中定義的屬性/方法名
issubclass (c) boolean 判斷是不是一個類的子類.
reparent (c) 函數 修改父類. ,當你想一個對象改變類型,這是非常有用.
對象
getclass ( ) 類對象 返回對象的類
parentclass ( ) 類對象 返回對象的父類(如果存在)
parentcall (name, args……) value 價調用父類中定義的方法
特性:
*可作爲傳統prototype.js中class.create的替換功能
*靈活和可靠的仿super功能
*富足的類元信息,如列出類中定義的方法等
*動態reparenting ,允許改變現有類的父類
*動態類的改變,當你想要一個對象改變類。
用法
定義一個類:
是比較容易的, 類似class.create方法. 您只需指定classdef屬性,如下:
var MyClass = Class.define({
CLASSDEF : {
name: 'MyClass'
},
attribute: ...,
method : function(...) {
...
},
...
})
主要區別是,因爲定義時候的操作,以後你不能再改變myclass.prototype. 因此,如果你選擇使用class.define你應該使用MyClass類對象的方法,實現類的操作(改變父類,添加方法等) .
定義子類:
可以用class.define操作. 您只需在classdef中加上父類定義
var MySubclass = Class.define({
CLASSDEF : {
name: 'MySubClass',
parent: MyClass
},
...
})
調用父類的構造函數:
在子類中調用父類的構造函數,可以這麼做:
var MySubclass = Class.define({
...
initialize:function() {
this.parentClass().constructor().call(this)
...
}, ...
}
調用父類的一般方法:
如果MyClass定義了一個hello的方法,在mysubclass也定義的有hello方法,我們希望調用的是myclass的hello方法,我們可以這麼做:
var MySubclass = Class.define({
...
hello:function() {
// This is the "old way of doing it"
// MySubclass.parentClass.method("hello").call(this)
this.parentCall("hello")
...
}, ...
}
改變父類:
假定你有classb ,繼承classa ,你想在運行時classb繼承classa . 這可以:
classb.reparent ( classa2 )
這會自動更新所有的classb , 使得classa2成爲classb的新父類