日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Javascript面向?qū)ο髷U(kuò)展庫

 CevenCheng 2012-05-24

Javascript面向?qū)ο髷U(kuò)展庫

最近一直在用js做項目,遇到了許多需要應(yīng)用面向?qū)ο髞碓O(shè)計的功能,由于js對OOP的原生支持還不是很完善,所以就寫了一個面向?qū)ο蟮臄U(kuò)展庫用做底層支持,現(xiàn)在把它單獨(dú)整理出來,完善了一些功能,在這里分享一下。
lang.js庫提供了包和類的定義、類的繼承與混合(mixin)、函數(shù)重載等功能,基本可滿足大多數(shù)面向?qū)ο笤O(shè)計的需求。同時支持基于鏈?zhǔn)降亩x方式,讓庫在使用時更加規(guī)范和便捷。下面首先通過簡單的例子演示了lang.js的基本功能,之后給出了lang.js的源碼及注釋。

 

一.功能介紹
“l(fā)ang”作為框架的全局定義,其中包括了四個方法:
lang.Package(string name) //用于定義包(默認(rèn)會暴露到全局)
lang.Class(string name[, object config], object classBody) //用于定義類
lang.Object(string name | object body) //用于定義支持重載函數(shù)的普通對象
lang.Function(string name | object body) //用于定義重載函數(shù)

 

復(fù)制代碼
//1.基本的包和類的定義:
//
首先通過全局函數(shù)Package定義一個包,下面可通過鏈?zhǔn)秸{(diào)用向包中定義類、對象或函數(shù)。

Package('com.site').

Class('Base',{
    Base: function(tagName){
        this.element = document.createElement(tagName);
    },
    add: function(child){
        this.element.appendChild(child);
    },
    show: function(){
        alert('I am Base!');
    }
}).

Class('Control', {
    Control: function(){
        //do soming
    }
});

alert(com.site);
alert(com.site.Base);
alert(com.site.Control);


//2.普通對象定義
//
一個不需初始化的類,可直接定義成普通對象
Package('com.site.util').

Object({
    ModelA: {
        say: function(){
            alert('ModelA: Hello!');
        } 
    },
    ModelB: {
        print: function(){
            alert('ModelB: ' + this.Class.Type.name);
        } 
    }
});
com.site.util.ModelA.say();


//3.類的繼承

//像很多面向?qū)ο笳Z言一樣,這里約定一個類只能擁有一個父類。但是可以通過mixin混合多個普通對象。
//
在子類的構(gòu)造函數(shù)中可以通過this.base訪問父類的構(gòu)造函數(shù)。
//
如子類定義了與父類相同函數(shù),父類函數(shù)將被重寫,這里同樣可以通過this.base調(diào)用父類被重寫的函數(shù)。
Package('com.site').

Class('Panel', {extend: com.site.Base, mixin:[com.site.util.ModelA, com.site.util.ModelB]}, {
    Panel: function(tagName){
        //這里使用this.base調(diào)用父類構(gòu)造函數(shù)
        this.base(tagName);
    },
    show: function(){
        alert('I am Panel!');
        this.base();
    }
});


var panel = new com.site.Panel("div");
panel.say();
panel.print();
alert(panel.element.outerHTML);

//4.靜態(tài)成員的定義
/*

程序中可以將類的主體以函數(shù)的形式定義,將私有成員定義在函數(shù)內(nèi)部,將公共成員以返回值的形式暴露出來。這種設(shè)計模式在很多流行框架中都可以看到,雖然隱藏的成員只能是靜態(tài)的,不過這也足以滿足大部分的需求了。
公有的靜態(tài)成員可以通過Static標(biāo)簽定義,Static中可包含一個靜態(tài)構(gòu)造函數(shù),該函數(shù)只會在類第一次創(chuàng)建的時候執(zhí)行一次。
在運(yùn)行期間類的內(nèi)部可以通過this.Class.xxx的形式訪問自身的靜態(tài)成員,(this.Class就是所屬類的引用)
*/

Package('com.site').

Class('Button', {extend: com.site.Panel}, function(){

    //在這里定義私有靜態(tài)成員
    var tagName = 'BUTTON';
    var onclick = function(){
        alert('I am a Button!');
    }

    return {
        //這里定義共有靜態(tài)成員
        Static: {
            count: 1,
            //靜態(tài)構(gòu)造函數(shù)
            Button: function(){
                this.createTime = new Date();
            }
        },
        Button: function(text){
            this.base(tagName);
            this.element.innerHTML = text;
            this.element.onclick = onclick;
            //調(diào)用靜態(tài)變量
            this.Class.count++;
        }
    };
});

var button = new com.site.Button("Button1");
document.body.appendChild(button.element);
alert(com.site.Button.count);

//5.重載函數(shù)的定義
/*

lang.js中對函數(shù)重載提供了較完善的支持,在定義函數(shù)時可在函數(shù)名后面指定參數(shù)簽名,調(diào)用函數(shù)時程序根據(jù)傳入的參數(shù)自動匹配轉(zhuǎn)發(fā)。
其中支持的類型包括:var,string,number,boolean,array,date,object,function,element和自定義的類(var表示任意類型,element表示DOM元素。)
為了保證靈活性,重載支持通配符功能,遵循正則表達(dá)式的規(guī)則,可以通過標(biāo)記“+ * ? {?,?}”來處理不確定參數(shù)個數(shù)的情況。
重載函數(shù)在類的繼承過程中是有效的,簽名不同的函數(shù)不會被重寫,被重寫的父類重載函數(shù)同樣支持通過this.base調(diào)用。
以下代碼為重載在類中應(yīng)用的例子:
*/

Package('com.site').

Class('Student',{
    Static: {
        //靜態(tài)函數(shù)重載
        'create()': function(){
            //這里的this就是類本身,所以可以直接new
            return new this('靜態(tài)', 1);
        },
        'create(string, number)': function(name, age){
            return new this(name, age);
        },
        'search()': function(){
            alert('search(*)');
        },
        'search(string)': function(name){
            alert('search('+name+')');
        }
    },
    //構(gòu)造函數(shù)重載
    'Student()': function(){
        //利用this.self調(diào)用自身構(gòu)造函數(shù)"Student(string, number)"
        this.self('未知', 0);
    },
    'Student(string, number)': function(name, age){
        this.name = name;
        this.age = age;
    },
    //普通成員函數(shù)重載
    'print()': function(){
        this.print(this.name ,this.age);
    },
    'print(string, number)': function(name, age){
        alert('name:' + name + ',age:' + age);
    },
    //支持自定義類的類型
    'print(lib.ui.Panel)': function(panel){
        this.print(panel, true);
    },
    'print(lib.ui.Panel, boolean)': function(panel, append){
        if(append){
            panel.element.innerHTML += this.name;
        }else{
            panel.element.innerHTML = this.name;
        }
    }
}).

//繼承中對重載的支持
Class('MaleStudent',{extend: com.site.Student},{
    Static: {
        //重寫父類靜態(tài)函數(shù)
        'search(string)': function(name){
            alert('MaleStudent: search('+name+')');
        },
        'search(string, number)': function(name, age){
            alert('MaleStudent: search('+name+','+age+')');
        }
    },
    'MaleStudent': function(){
        //調(diào)用父類的構(gòu)造函數(shù)"Student(string, number)"
        this.base('未知男同學(xué)', 0);
    },
    'MaleStudent(string, number)': function(name, age){
        //調(diào)用父類的構(gòu)造函數(shù)"Student(string, number)"
        this.base(name, age);
    },
    //重寫了父類的重載函數(shù)
    'print()': function(){
        alert('MaleStudent: name:' + this.name + ',age:' + this.age);
    },
    'print(string, number)': function(name, age){
        //通過this.base調(diào)用父類函數(shù)"print(string, number)"
        this.base('<'+name+'>', '<' + age + '>');
    },
    //模糊匹配,這個函數(shù)可接受一個或多個字符串和零個或多個數(shù)字
    'print(string+, number*)': function(){
        var msg = [];
        for(var i=0; i<arguments.length; i++){
            msg.push(arguments[i]);
        }
        alert('print(string+, number*):' + msg.join('+'));
    }
});

//創(chuàng)建對象時會自動判斷調(diào)用的構(gòu)造函數(shù)
var studentA = new com.site.Student();
studentA.print();

var studentB = new com.site.MaleStudent('王小虎', 19);
studentB.print();
studentB.print('小虎', 19);

//這里調(diào)用了模糊匹配的重載函數(shù)
studentB.print('a','b','c');
studentB.print('x','y','z', 1, 2 ,3);

var studentC = new com.site.MaleStudent();
studentC.print();

//調(diào)用靜態(tài)重載函數(shù)
var student = com.site.Student.create();
student.print();
com.site.Student.search();
com.site.Student.search('某同學(xué)');

//共有的靜態(tài)函數(shù)會繼承到子類,所以MaleStudent也可以create
var maleStudent = com.site.MaleStudent.create('小紅', 18);
maleStudent.print();
com.site.MaleStudent.search('小明');
com.site.MaleStudent.search('小明',20);

//6.匿名定義
//
有些時候,我們不希望顯示的指定一個類或函數(shù)的名字,只希望把它保存到變量里面,那么可以通過匿名的方式進(jìn)行定義。

//1)使用lang.Class創(chuàng)建匿名類
var clazz = lang.Class({
    //匿名類的名字統(tǒng)一為Anonymous,所以構(gòu)造函數(shù)的名字也要是Anonymous
    Anonymous: function(name){
        this.name = name;
    },
    show: function(){
        alert(this.name);
    }
});

alert(clazz);
new clazz('匿名類').show();

//2)使用lang.Function創(chuàng)建匿名重載函數(shù)
var fn = lang.Function({
    '(default)': function(){
        var a = [].slice.call(arguments, 0);
        alert(a);
    },
    '(string)': function(a){
        alert('(string): ' + a);
    },
    '(string, number)': function(a, b){
        alert('(string, number): ' + a + ':' + b);
    },
    '(number)': function(a){
        alert('(number): ' + a);
    }
});

alert(fn);
fn('message');
fn('message', 1);
fn(1);
fn(1,2,3,4,5);

//3)使用lang.Object創(chuàng)建支持重載函數(shù)的普通對象
var obj = lang.Object({
    name: 'jim',
    'write()': function(){
        this.write(this.name);
    },
    'write(string)': function(name){
        alert(name);
    }
});

obj.write();
obj.write('joe');


//7.綜合例子
Package("com.site").

Class('ClassA', {
    print: function(){
        alert(this.toString());
    }
}).

Class('ClassB', {
    print: function(){
        alert(this.toString());
    }
}).

Object({
    fn1: function(){
        alert(1);
    },
    fn2: function(){
        alert(2);
    },
    'debug(string)': function(msg){
        alert(msg);
    },
    'debug(string, number)': function(msg, num){
        alert(num + ': ' + msg);
    },
    'debug(com.site.ClassA, string)': function(c, method){
        alert('debug ClassA');
        c[method]();
    },
    'debug(com.site.ClassB, string)': function(c, method){
        alert('debug ClassB');
        c[method]();
    },
    'debug(element)': function(element){
        alert('element:' + element.outerHTML);
    }
}).

Object('Web', {
    'reload': function(){
        alert('reload...');
    },
    'reload(function)': function(fn){
        fn();
    }
}).

Package('com.site.util').

Function('myfn(string)', function(name){
    alert(name);
}).

Function('myfn(number)', function(num){
    alert(num*num);
}).

Class('ClassA', {
    ClassA: function(){
        alert('ClassA!');
    }
});

var div = document.createElement("div");
var span = document.createElement("span");
div.appendChild(span);

com.site.fn1();
com.site.fn2();
com.site.debug('info');
com.site.debug('info', 1);
com.site.debug(new com.site.ClassA(), 'print');
com.site.debug(new com.site.ClassB(), 'print');
com.site.debug(div);
com.site.Web.reload();
com.site.Web.reload(function(){alert('callback');});
com.site.util.myfn('Jim');
com.site.util.myfn(100);
new com.site.util.ClassA();


//8.自描述信息
/*

自描述就是類或?qū)ο笤诙x完成后對自身的信息的描述,常常用于實現(xiàn)一些特殊的功能,庫中通過Type"保留字"存儲類或包的自描述信息。
下面為使用方法:
*/

var value = com.site.Student;
alert('判斷是否一個類:' + (value.Type && value.Type.type == 'class'));
alert('取完整類名:' + com.site.Student.Type.name);
alert('取父類完整類名:' + com.site.MaleStudent.Type.baseClass.Type.name);
alert('取短類名:' + com.site.Student.Type.shortName);
alert('取一個類的包名:' + com.site.Student.Type.Package.Type.name);
復(fù)制代碼
 

二.源碼詳解

復(fù)制代碼
var lang = (function(){
/***********************************
 Javascript面向?qū)ο髷U(kuò)展庫(lang.js v1.0)
 By: X!ao_f
 QQ: 120000512
 Mail: xiao_f.mail#163.com
***********************************
*/

var customToString = function(){
    return '[' + this.Type.type +  ' ' + this.Type.name + ']';
}

//支持重載的方法定義
var createMethod = (function(){
    
    //創(chuàng)建一個代理函數(shù)
    var createMethodProxy = function(context, name){
        //當(dāng)調(diào)用重載的函數(shù)時,首先會執(zhí)行該函數(shù)分析傳入的參數(shù),進(jìn)行匹配和轉(zhuǎn)發(fā)
        var method = function(){
            //在第一次調(diào)用時初始化,將映射信息緩存
            if(!method.__initialized__){
                initializeMethod(method);
            }

            //將參數(shù)類型拼接成函數(shù)簽名
            var signature;
            if(arguments.length){
                var list = [];
                for(var i=0; i<arguments.length; i++){
                    var typename;
                    var argument = arguments[i];
                    if(argument === undefined || argument === null){
                        typename = 'object';
                    }else if(argument instanceof Array){
                        typename = 'array';
                    }else if(argument instanceof Date){
                        typename = 'date';
                    }else{
                        typename = typeof argument;
                        if(typename == 'object'){
                            if('Class' in argument){
                                typename = argument.Class.Type.name;
                            }else if('nodeType' in argument){
                                typename = 'element';
                            }
                        }
                    }
                    list.push(typename);
                }
                signature = list.join(',');
            }else{
                signature = '';
            }
            //如果常規(guī)緩存中存在匹配的簽名,直接調(diào)用
            if(method.__overloads__[signature]){
                return method.__overloads__[signature].apply(this, arguments);
            }else{
                //緩存中不存在時,嘗試?yán)谜齽t進(jìn)行模糊匹配
                //首先判斷模糊匹配緩存中是否存在記錄,如存在直接調(diào)用
                if(method.__overloadsCache__[signature]){
                    return method.__overloadsCache__[signature].apply(this, arguments);
                }
                //循環(huán)匹配
                for(var i=0; i<method.__overloadsRegExp__.length; i++){
                    //如果匹配成功,將映射關(guān)系存入模糊匹配緩存,同時調(diào)用并返回
                    if(method.__overloadsRegExp__[i].regexp.test(signature)){
                        method.__overloadsCache__[signature] = method.__overloadsRegExp__[i].fn;
                        return method.__overloadsRegExp__[i].fn.apply(this, arguments);
                    }
                }
                //如果依然無法找到對應(yīng)的函數(shù),判斷是否存在默認(rèn)函數(shù)
                if(method.__overloads__['default']){
                    return method.__overloads__['default'].apply(this, arguments);
                }else if(method.__overloads__['']){
                    return method.__overloads__[''].apply(this, arguments);
                }else{
                    alert('Error: '+method.Type.name+'('+signature+') is undefined.');
                }
            }
        };
        //內(nèi)置對象
        method.__context__ = context;
        method.__functions__ = {};
        method.toString = customToString;
        //自描述信息
        method.Type = {
            name: name,
            Method: method,
            type: 'method'
        };
        return method;
    }

    //初始化
    var initializeMethod = function(method){
        //基礎(chǔ)簽名緩存
        method.__overloads__ = {};
        //模糊匹配正則緩存
        method.__overloadsRegExp__ = [];
        //模糊匹配結(jié)果緩存
        method.__overloadsCache__ = {};
        //例舉所有定義的函數(shù)
        for(var signature in method.__functions__){
            var fn = method.__functions__[signature];
            var params = signature.substring(signature.indexOf('(') + 1, signature.length - 1);
            var pure = !/[\*\+\?\{]/.test(params);
            //如果不存在通配符直接保存到基礎(chǔ)簽名緩存   
            if(pure){
                method.__overloads__[params] = fn;
            }else{
                //生成模糊匹配正則
                var regexp = '^' + params
                    .replace(/([\w\.]+)(\{.*?\})?/g, '($1(,|$))$2')
                    .replace(/\./g, '\\.')
                    .replace(/((\()var(\())/g, '$2\\w+$3')
                    .replace(/,\(/g, '(') + '$';
                method.__overloadsRegExp__.push({ regexp: new RegExp(regexp), fn: fn });
            }
        }
        method.__initialized__ = true;
    }
    
    //返回外部的定義函數(shù)
    return function(signature, fn, comp){
        //如果傳入的為一個對象,視為定義匿名方法
        if(typeof signature == 'object'){
            var context = {};
            var method;
            for(var key in signature){
                method = createMethod.call(context, 'anonymous'+key, signature[key]);
            }
            return method;
        }

        signature = signature.replace(/\s+/g, '');
        var index = signature.indexOf('(');
        var name = index > -1 ? signature.substring(0, signature.indexOf('(')) : signature;
        var context = this;
        var method = context[name];

        //上下文中不存在函數(shù)定義,視為第一次定義
        if(method === undefined){
            context[name] = method = createMethodProxy(context, name);
        }else if(!method.Type || method.Type.type!='method'){
            //上下文存在的函數(shù)是原生函數(shù),將這個函數(shù)作為默認(rèn)函數(shù)存入列表
            var temp = method;
            context[name] = method = createMethodProxy(context, name);
            method.__functions__[name + '()'] = temp;
        }else{
            //如果上下文不同,創(chuàng)建新的重載方法并將已經(jīng)存在的函數(shù)復(fù)制,這里主要解決類繼承中子類與父類沖突的問題
            //如果上下文相同,直接將初始化標(biāo)記設(shè)為false,待下次調(diào)用時重新初始化
            if(method.__context__ !== context){
                var temp = method;
                context[name] = method = createMethodProxy(context);
                for(var sign in temp.__functions__){
                    method.__functions__[sign] = temp.__functions__[sign];
                }
            }else{
                method.__initialized__ = false;
            }
        }
        //將本次定義的函數(shù)添加到函數(shù)列表
        //先入為主策略
        if(comp){
            if(fn.__functions__){
                for(var key in fn.__functions__){
                    if(key in method.__functions__){
                        method.__functions__[key].__overridden__ = fn;
                    }else{
                        method.__functions__[key] = fn;
                    }
                }
            }else{
                if(signature in method.__functions__){
                    method.__functions__[signature].__overridden__ = fn;
                }else{
                    method.__functions__[signature] = fn;
                }
            }
        }else{
            //后入為主策略
            if(fn.__functions__){
                for(var key in fn.__functions__){
                    if(key in method.__functions__){
                        fn.__functions__[key].__overridden__ = method;
                    }
                    method.__functions__[key] = fn.__functions__[key];
                }
            }else{
                if(signature in method.__functions__){
                    fn.__overridden__ = method;
                }
                method.__functions__[signature] = fn;
            }
        }
        if(this.Type && this.Type.type == 'package'){
            return this;
        }else{
            return method;
        }
    };
})();


//類定義函數(shù)
var createClass = (function(){
    var slice = Array.prototype.slice;
    var emptyFn = function(){};

    var createClass = function(name){
        return function(){
            this[name].apply(this, slice.call(arguments, 0));
        };
    }

    //用于調(diào)用被重寫函數(shù)
    var baseCaller = function(){
        if(arguments.length){
            var args = slice.call(arguments, 0);
            return baseCaller.caller.__overridden__.apply(this, args);
        }else{
            return baseCaller.caller.__overridden__.call(this);
        }
    }

    //用于調(diào)用自身重載構(gòu)造函數(shù)
    var selfCaller = function(){
        if(arguments.length){
            var args = slice.call(arguments, 0);
            return selfCaller.caller.__self__.apply(this, args);
        }else{
            return selfCaller.caller.__self__.call(this);
        }
    }

    var filter = {prototype:true, Type:true};
        
    //快速淺拷貝
    function clone(a){
        var fn = function(){};
        fn.prototype = a;
        return new fn;
    }

    //對象復(fù)制,替換存在的(后入為主)
    function replace(base, self){
        for(var key in self){
            if(!(key in filter)){
                if(typeof self[key] == 'function'){
                    //如果子類函數(shù)包含重載簽名或父類函數(shù)已經(jīng)重載
                    if(key.indexOf('(') > -1 || (base[key] && base[key].__functions__)){
                        createMethod.call(base, key, self[key]);
                    }else{
                        //常規(guī)函數(shù)定義
                        if(key in base){
                            //記錄重寫信息
                            self[key].__overridden__ = base[key];
                        }
                        base[key] = self[key];
                    }
                }else{
                    base[key] = self[key];
                }
            }
        }
    }

    //對象復(fù)制,只取補(bǔ)集(先入為主)
    function complement(self, base){
        for(var key in base){
            if(!(key in filter)){
                if(typeof base[key] == 'function'){
                    if(key.indexOf('(') > -1 || (self[key] && self[key].__functions__)){
                        createMethod.call(self, key, base[key], true);
                    }else{
                        if(key in self){
                            //記錄重寫信息
                            self[key].__overridden__ = base[key];
                        }else{
                            self[key] = base[key];
                        }
                    }
                }else if(!(key in self)){
                    self[key] = base[key];
                }
            }
        }
    }

    return function(){
        //處理參數(shù)
        if(this.Type && this.Type.type == 'package'){
            if(arguments.length == 2){
                var name = arguments[0];
                var body = arguments[1];
            }else{
                var name = arguments[0];
                var config = arguments[1];
                var body = arguments[2];
            }
        }else{
            if(arguments.length == 1){
                var name = 'Anonymous';
                var body = arguments[0];
            }else{
                var name = 'Anonymous';
                var config = arguments[0];
                var body = arguments[1];
            }
        }

        //創(chuàng)建類的基礎(chǔ)函數(shù)
        var clazz = createClass(name);
        
        //獲取父類信息
        var baseClass;
        if(config && config.extend){
            baseClass = config.extend;
        }

        //如果傳入的主體為函數(shù),取其返回值
        if(typeof body == 'function'){
            body = body(clazz);
        }

        //處理靜態(tài)成員
        if(body.Static){
            complement(clazz, body.Static);
            delete body.Static;
            body = body.Public||body;
        }else{
            body = body.Public||body;
        }
        
        //處理繼承
        if(baseClass){
            //通過快速淺拷貝復(fù)制父類成員
            clazz.prototype = clone(baseClass.prototype);
            //繼承靜態(tài)成員
            complement(clazz, baseClass);
            //繼承類成員
            complement(clazz.prototype, body);
        }else{
            //不存在繼承
            clazz.prototype = {};
            complement(clazz.prototype, body);
        }

        //處理混合
        if(config && config.mixin){
            var mixin = config.mixin;
            if(mixin instanceof Array){
                for(var i=0; i<mixin.length; i++){
                    replace(clazz.prototype, mixin[i]);
                }
            }else{
                replace(clazz.prototype, mixin);
            }
        }
        //添加內(nèi)置函數(shù)
        clazz.prototype.base = baseCaller;
        clazz.prototype.self = selfCaller;
        clazz.prototype.constructor = clazz;
        clazz.prototype.toString = customToString;
        clazz.toString = customToString;
        clazz.prototype.Class = clazz;
        if(clazz.prototype[name]){
            var constructor = clazz.prototype[name];
            if(constructor.__functions__){
                for(var key in constructor.__functions__){
                    //存在重載時,添加自身引用,用于通過this.self調(diào)用重載構(gòu)造函數(shù)
                    constructor.__functions__[key].__self__ = constructor;
                    //存在繼承時,將父類的構(gòu)造函數(shù)作為被重寫的函數(shù),配置給當(dāng)前類的構(gòu)造函數(shù)
                    //用于通過base調(diào)用父類構(gòu)造函數(shù)
                    if(baseClass){
                        constructor.__functions__[key].__overridden__ = baseClass.prototype[baseClass.Type.shortName];
                    }
                }
            }else if(baseClass){
                clazz.prototype[name].__overridden__ = baseClass.prototype[baseClass.Type.shortName];
            }
        }else{
            clazz.prototype[name] = emptyFn;
        }
        //類型自描述信息
        //如果當(dāng)前上下文是一個包,將類添加到包中
        if(this.Type && this.Type.type == 'package'){
            clazz.Type = {
                type:'class',
                name: this.Type.name+'.'+name,
                shortName: name,
                Package: this,
                Class: clazz,
                baseClass: baseClass
            }
            clazz.prototype.Type = {
                type: 'object',
                name: this.Type.name+'.'+name
            }
            //將類添加到包
            this[name] = clazz;
            //調(diào)用靜態(tài)構(gòu)造函數(shù)
            if(name in clazz){
                clazz[name].call(clazz);
            }
            //返回this用于鏈?zhǔn)秸{(diào)用
            return this;
        }else{
            //上下文不是包則直接返回
            clazz.Type = {
                type:'class',
                name: name,
                shortName: name,
                Class: clazz,
                baseClass: baseClass
            }
            clazz.prototype.Type = {
                type: 'object',
                name: name,
                baseClass: baseClass
            }
            if(name in clazz){
                clazz[name].call(clazz);
            }
            return clazz;
        }
    };
})();


//用于創(chuàng)建支持重載的普通對象
var createObject = function(objects, config){
    var target;
    if(this.Type && this.Type.type == 'package'){
        target = this;
    }else{
        target = {};
    }
    if(typeof objects == 'string'){
        target = this[objects] = {};
        objects = config;
    }else if(typeof objects == 'function'){
        objects = objects();
    }
    for(var key in objects){
        if(typeof objects[key] == 'function' && (key.indexOf('(') > -1 || typeof target[key] == 'function')){
            createMethod.call(target, key, objects[key]);
        }else{
            target[key] = objects[key];
        }
    }
    if(this.Type && this.Type.type == 'package'){
        return this;
    }else{
        return target;
    }
};


//用于創(chuàng)建包
var createPackage = (function(){
    var root = this;
    return function(package){
        var name = [];
        var path = package.split('.');
        var parent = root;
        for(var i=0; i<path.length; i++){
            name.push(path[i]);
            if(parent[path[i]]){
                parent = parent[path[i]];
            }else{
                var pack = {
                    Class: createClass,
                    Object: createObject,
                    Function: createMethod,
                    Package: createPackage,
                    toString: customToString
                };
                pack.Type = {
                    type: 'package',
                    Package: pack,
                    name: name.join('.')
                }
                parent = parent[path[i]] = pack;
            }
        }
        return parent;
    }
})();

//默認(rèn)將Package暴露
window.Package = createPackage;
return {
    Package: createPackage,
    Class: createClass,
    Function: createMethod,
    Object: createObject
};
})();
復(fù)制代碼
 

結(jié)束語:

到這里,lang.js的應(yīng)用和原理就介紹完畢了,該庫在主流瀏覽器中均已測試通過,
如果想使用lang.js,可以在這里免費(fèi)下載,如發(fā)現(xiàn)什么問題,或有好的建議可以反饋給我。

 

標(biāo)簽: Javascript框架設(shè)計

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多