dom Framework的类工厂模块,方便人们设计健壮的类与层次清晰的继承体系,这对UI库的构建作用非常明显。
本版本的改进,摒弃ruby风格的include API,更名为implement,走近javaer。同时修复implement方法的一个BUG,让用户可以重写toString与valueOf这两个特殊的原型方法。
//=========================================
// 类工厂模块
//==========================================
(function(global,DOC){
var dom = global[DOC.URL.replace(/(#.+|\W)/g,'')];
dom.define("class", "lang",function(){
// dom.log("已加载class模块")
var
P = "prototype", C = "constructor", I = "@init",S = "_super",
unextend = dom.oneObject([S,P, 'extend', 'implement','_class']),
exclusive = new RegExp([S,I,C].join("|")),ron = /on([A-Z][A-Za-z]+)/,
classOne = dom.oneObject('Object,Array,Function');
function expand(klass,props){
'extend,implement'.replace(dom.rword, function(name){
var modules = props[name];
if(classOne[dom.type(modules)]){
klass[name].apply(klass,[].concat(modules));
delete props[name];
}
});
return klass
}
function setOptions(){
var options = this.options = dom.Object.merge.apply(this.options || {}, arguments),key,match
if (typeof this.bind == "function") {
for (key in options) {
if ((match = key.match(ron))) {
this.bind(match[1].toLowerCase(), options[key]);
delete(options[key]);
}
}
}
return this;
}
function _super(){
var caller = arguments.callee.caller; // 取得当前方法
var name = caller._name; // 取得当前方法名
var superclass = caller._class[S];//取得当前实例的父类
if(superclass && superclass[P][name] ){
return superclass[P][name].apply(this, arguments.length ? arguments : caller.arguments);
}else{
throw name + " no super method!"
}
}
dom["@class"] = {
inherit : function(parent,init) {
var bridge = function() { }
if(typeof parent == "function"){
for(var i in parent){//继承类成员
this[i] = parent[i]
}
bridge[P] = parent[P];
this[P] = new bridge;
;//继承原型成员
this[S] = parent;//指定父类
}
this[I] = (this[I] || []).concat();
if(init){
this[I].push(init);
}
this.toString = function(){
return (init || bridge) + ""
}
var KP = this[P];
KP.setOptions = setOptions;
KP[S] = _super;//绑定方法链
return KP[C] = this;
},
implement:function(){
var target = this[P], bridge = {},reg = exclusive;
for(var i = 0, module; module = arguments[i++]; ){
if(dom.type(module,"Object")){
dom.mix(bridge, module);
}else if(typeof module === "function"){
dom.mix(bridge, new module);
}
}
Object.keys(bridge).forEach(function(name){
if(!reg.test(name)){
var prop = target[name] = bridge[name];
if(typeof prop == "function"){
prop._name = name;
prop._class = this;
}
}
},this);
return this;
},
extend: function(){//扩展类成员
var bridge = {}
for(var i = 0, module; module = arguments[i++]; ){
dom.mix(bridge, module);
}
for(var key in bridge){
if(!unextend[key]){
this[key] = bridge[key]
}
}
return this;
}
};
dom.factory = function(obj){
obj = obj || {};
var parent = obj.inherit //父类
var init = obj.init ; //构造器
delete obj.inherit;
delete obj.init;
var klass = function () {
for(var i = 0 , init ; init = klass[I][i++];){
init.apply(this, arguments);
}
};
dom.mix(klass,dom["@class"]).inherit(parent, init);//添加更多类方法
return expand(klass,obj).implement(obj);
}
});
})(this,this.document);
//2011.7.11
//dom["class"]改为dom["@class"]
//2011.7.25
//继承链与方法链被重新实现。
//在方法中调用父类的同名实例方法,由$super改为supermethod,保留父类的原型属性parent改为superclass
//2011.8.6
//在方法中调用父类的同名实例方法,由supermethod改为_super,保留父类的原型属性superclass改为_super
//重新实现方法链
//fix 子类实例不是父类的实例的bug
//2011.8.14 更改隐藏namespace,增强setOptions
//2011.10.7 include更名为implement 修复implement的BUG(能让人重写toString valueOf方法)
一些测试:
dom.require("ready,class",function(){
var Ancestor = dom.factory({
init:function(name){
this.name = name;
},
ancestor_prop:"3333333",
instance_fn:function(){
return "ancestor_instance"
},
instance_fn2:function(){
return "ancestor_instance2"
},
extend:{
class_fn:function(){
return "ancestor_class";
}
}
});
var Parent = dom.factory({
inherit:Ancestor,
instance_fn:function(){
return this._super()+"-->Parent";
},
extend:{
class_fn:function(){
return "parent_class";
}
}
});
var Son = dom.factory({
inherit:Parent,
init:function(name,age){
this.age = age;
},
instance_fn2:function(){
return this._super()+"-->Son";
},
instance_fn3:function(){
return "instance_fn3"
},
extend:{
class_fn:function(){
return "son_class";
}
}
});
var p = new Parent("john");
dom.log(p.instance_fn())
dom.log(Parent.class_fn())
var s = new Son("nasami", 14);
dom.log(s.instance_fn())
dom.log(s.instance_fn2())
dom.log(Son.class_fn())
dom.log(s.age)
dom.log(s.name)
var a = new Ancestor("时光之轮",30);
dom.log(a.age)
dom.log(a.name)
dom.log(s instanceof Parent)
});
相关链接:
dom Framework oop模块 v6dom Framework oop模块 v5
dom Framework oop模块 v4
dom Framework oop模块 v3