面向對象Javascript核心支持代碼

    JQury框架絕對是首先頁面開發的首選,代碼短小強悍,缺點就是面向對象特性不足,所幸有不少插件!至於Ext就是一個龐然大物了,高度面向對象,類似於MFC的龐大API和控件庫,運行起來,瀏覽器就累得夠嗆,開發也夠嗆,使用代碼來創建界面絕對是個糟糕的方式,Javascript的弱語言類型使得Ext開發就像行走在雷區,減少bug的唯一方法就是不要寫出bug,一旦出現bug,調試將是一件極爲痛苦的事情 !在幾千行代碼裏跟蹤、跳轉真讓人抓狂!

     Javascript做面向對象開發的時候,總是會用到很多模擬面向對象特性的方法,這些方法就構成了支撐面向對象Javascript的核心代碼,以下就是部分代碼,其中參考了很多JQuery與Ext的核心代碼,用來學習還不錯,也可以做一些小的開發!

/*
功能:核心腳本方法
作者:LQB
2008-12-22
*/
var JCore = {//構造核心對象
    version:1.0,
    $import:function(importFile){
        var file = importFile.toString();
        var IsRelativePath = (file.indexOf("$")==0 ||file.indexOf("/")==-1);//相對路徑(相對於JCore)
        var path=file;
        if(IsRelativePath){//計算路徑
            if(file.indexOf("$")==0)
                file = file.substr(1);
            path = JCore.$dir+file;
        }
        var newElement=null,i=0;
        var ext = path.substr(path.lastIndexOf(".")+1);
        if(ext.toLowerCase()=="js"){
            var scriptTags = document.getElementsByTagName("script");
            for(var i=0;ilength;i++) {  
                if(scriptTags[i].src && scriptTags[i].src.indexOf(path)!=-1)
                    return;
            }
            newElement=document.createElement("script");
            newElement.type="text/javascript";
            newElement.src=path;
        }
        else if(ext.toLowerCase()=="css"){
            var linkTags = document.getElementsByTagName("link");
            for(var i=0;iTags.length;i++) {
                if(linkTags[i].href && linkTags[i].href.indexOf(path)!=-1)
                    return;
            }
            newElement=document.createElement("link");
            newElement.type="text/css";
            newElement.rel="Stylesheet";
            newElement.href=path;
        }
        else
            return;
        var head=document.getElementsByTagName("head")[0];
        head.appendChild(newElement);
    },
    $dir : function(){
            var scriptTags = document.getElementsByTagName("script");
            for(var i=0;ilength;i++) {  
                if(scriptTags[i].src && scriptTags[i].src.match(/JCore/.js$/)) {  
                    path = scriptTags[i].src.replace(/JCore/.js$/,"");   
                    return path;
                }
            }
            return "";
    }(),
    $ : function(element){
	        return (typeof(element) == 'object' ? element : document.getElementById(element));
	    },
	browser : {
	    isFirefox:navigator.userAgent.toLowerCase().indexOf ('gecko') != -1,
	    isChrome:navigator.userAgent.toLowerCase().indexOf ('chrome') != -1,
	    isOpera:navigator.userAgent.toLowerCase().indexOf ('opera') != -1,
	    isIE:navigator.userAgent.toLowerCase().indexOf ('msie') != -1,
	    isIE7:navigator.userAgent.toLowerCase().indexOf ('7.0') != -1
    },
	onReady: function(newFunction){
		if(typeof(newFunction) == 'undefined')
			return false;
		this.domReady = false;
		if(typeof(functions) == 'undefined')
			var functions = [];
		functions.push(newFunction);
		
		var initial = function(){//執行事件列表
			for(var i=0; i< functions.length;i++){
				functions[i]();
			}
		}
		this.ready = function(){//加載事件
			if(this.domReady)
				initial();
			var Browser = JCore.browser;	
			if (Browser.isFirefox || Browser.isOpera || Browser.isChrome) {//FX
				try {
					document.removeEventListener('DOMContentLoaded', initial);
				}catch(e){}
				document.addEventListener('DOMContentLoaded', initial, false);
				this.domReady = true;
			}
			else if (Browser.isIE) {//IE
				var timer = window.setInterval(function(){
					try {
					    var IsReady = false;
						document.body.doScroll("left");
						IsReady=true;
						initial();
						window.clearInterval(timer);
						this.domReady = true;
					} 
					catch (e){
					    if(IsReady){//文檔加載已經完畢,拋出異常說明是調用的方法出錯
					        var ErrorMsg = "onReady的方法中發生錯誤!/r/n";
					            ErrorMsg+="錯誤信息:"+e.message+"/r/n";
					            ErrorMsg+="錯誤描述:"+e.description+"/r/n";
					            ErrorMsg+="錯誤類型:"+e.name+"/r/n";
					            alert(ErrorMsg);
					            window.clearInterval(timer);
					    }
					}
				}
				, 5);	
			}
		}
	    this.ready();
	},
	apply:function(oDes, oSrc,bReplace){//爲對象拷貝其它對象的屬性,bReplace可選
        if(oDes && oSrc && typeof(oSrc) == 'object'){
            for(var p in oSrc){
                if(bReplace == false && oDes[p] != null) { continue; }
                oDes[p] = oSrc[p];
            }
        }
        return oDes;
    },
    override : function(origclass, overrides){//爲類增加重載方法,eg:override(function class(){},{A:function(){},B:function(){}});
            if(overrides){
                var p = origclass.prototype;
                for(var method in overrides){
                    p[method] = overrides[method];
                }
            }
        },
    extend  :function(){
            // inline overrides
            var inlineOverride = function(o){
                for (var m in o) {
                    this[m] = o[m];
                }
            };
            /*需要實現重載的基類方法需要在父類prototype中定義;
            * 在子類中方法的可見度:子類構造中的屬性>父類構造中的屬性>子類prototype定義的屬性==overrides>父類prototype定義的屬性
            * 由於overrides方法被附加到子類的prototype中,所以:子類prototype定義的屬性與overrides,兩者後定義的可見
            * extend方法將重寫子類的prototype,因此在子類的prototype上定義屬性則必須在extend()方法調用之後再定義纔有效
            * 對於一個類:構造中定義的屬性>prototype定義的屬性
            *
            *類派生的準則:
            *   1.建議把基類中可重寫的方法定義在基類prototype中
            *   2.如果在派生類的prototype中定義屬性方法,必須在extend()方法之後
            *   3.在派生類的構造中調用基類的構造:
            *       if(Sub.superclass) //sub即子類的名稱
            *           Sub.superclass.constructor.call(this, Args);//Args即父類的構造方法的參數
            *   4.注意數組的淺拷貝問題
            *示例:
            *   var ClassA=function(){this.Show=function(){alert("Hello World!");}};
            *   var ClassB=function(){};
            *   JCore.extend(ClassB,ClassA);
            *   var ObjectB = new ClassB();
            *   ObjectB.Show();
            */
            return function(subFn, superFn, overrides){//子類,父類,重載方法(可選)
                var F = function(){}, subFnPrototype, superFnPrototype = superFn.prototype;
                F.prototype = superFnPrototype;
                subFnPrototype = subFn.prototype = new F();
                subFnPrototype.constructor = subFn;
                subFn.superclass = superFnPrototype;//父類
                if (superFnPrototype.constructor == Object.prototype.constructor) {
                    superFnPrototype.constructor = superFn;
                }
                subFn.override = function(obj){//override
                    JCore.override(subFn, obj);
                };
                subFnPrototype.override = inlineOverride;
                if(overrides)
                    JCore.override(subFn, overrides);
                return subFn;
            };
    }(),//括號不可少,表示調用內部返回的方法
    namespace : function(ns){//eg: JCore.namespace("JCore", "JCore.util");
            var args=arguments, o=null, i, j, d, rt;
            for (i=0; ilength; ++i) {//遍歷參數
                d=args[i].split(".");//遍歷點分隔符
                rt = d[0];
                eval('if (typeof ' + rt + ' == "undefined"){' + rt + ' = {};} o = ' + rt + ';');
                for (j=1; jlength; ++j) {
                    o[d[j]]=o[d[j]] || {};
                    o=o[d[j]];
                }
            }
    },
    isEmpty : function(value){
            return value === null || typeof(value) === 'undefined' || value === '';
        },
    idSeed : 0,
    id : function(el, prefix){
            prefix = prefix || "JCore-gen";
            el = this.$(el);
            var id = prefix + (this.idSeed++);
            return el ? (el.id ? el.id : (el.id = id)) : id;
        }
};
/*--------------------------------------------Function對象擴展-------------------------------------------*/
var FunctionExtendMethod ={
    createCallback : function(/*args...*/){//此參數即創造者的參數
        /*示例:function func1(arg1,arg2){alert(arg1+arg2);}
         *      var myfunc = func1.createCallback(1,2);
         *      myfunc();//即調用了func1
        **/
        var args = arguments;
        var method = this;
        return function(/*args...*/) {//如果在調用時傳了參數,則創建時傳的參數無效
            var callArgs = arguments.length>0 ? arguments : args;
            return method.apply(window, callArgs);
        };
    },
    createDelegate : function(argsArray,scope){//參數可選
        //參數一個數組,與createCallback區別:createCallback參數是可變參數,createDelegate的argsArray參數必須是數組
        var method = this;
        return function(/*args...*/) {//如果在調用時傳了參數,則創建時傳的參數無效
            var callArgs = typeof(argsArray)=="undefined"?[]:argsArray;
            callArgs = arguments.length>0 ? arguments : callArgs;
            return method.apply(scope||window, callArgs);
        };
    },
    defer : function(millis/*,args...*/){//參數:延遲時間(毫秒),可選參數列表
        /*示例:function func1(arg1,arg2){alert(arg1+arg2);}
         *      func1.defer(1000,1,2);//延遲1秒調用了func1(1,2)
        **/
        var callArgs = Array.prototype.slice.call(arguments, 1);
        var fn = this.createDelegate(callArgs);
        if(millis){
            return setTimeout(fn, millis);
        }
        fn();
        return 0;
    },
    createInterceptor : function(fcn, scope){
        if(typeof fcn != "function"){
            return this;
        }
        var method = this;
        return function() {
            fcn.target = this;
            fcn.method = method;
            if(fcn.apply(scope || this || window, arguments) === false){
                return;
            }
            return method.apply(this || window, arguments);
        };
    }
 };
 JCore.apply(Function.prototype,FunctionExtendMethod);
 /*--------------------------------------------String對象擴展----------------------------------------*/
 var StringExtendMethod ={
        trim : function(){//去掉首尾空格
            return this.replace(/(^/s*)|(/s*$)/g,"");//將字符串前後空格,用空字符串替代。
        },
        replaceAll : function (AFindText,ARepText){//替換所有,replace只替換第一個
                        raRegExp = new RegExp(AFindText,"g");
                        return this.replace(raRegExp,ARepText);
        },
        htmlEncode : function(){//編碼HTML和解碼Html。過濾掉雙引號,單引號,符號&,符號<,符號
            return this.replace(/&/g,"&").replace(/,"<").replace(/>/g,">").replace(//"/g,""").replace(//'/g,"'");
        },
        htmlDecode : function(){
            return this.replace(//&amp/;/g, '/&').replace(//&gt/;/g, '/>').replace(//&lt/;/g, '/<').replace(//&quot/;/g, '/'').replace(//&/#39/;/g, '/'');
        },
        format : function(){
            var args=arguments;
            return this.replace(//{(/d+)/}/g, function(m, i){
                    return args[i];
            });
        },
        convertWarpSymbol : function(){
            var reg1,reg2,reg3;
            if(this.toLowerCase().indexOf("
")!=-1){ reg1 = / /gi; reg2 = //gi; return this.replace(reg1," ").replace(reg2,"/r/n"); } else{ reg1 = / /g;reg2 = //r/n/gi; return this.replace(reg1," ").replace(reg2,"
"); } }, IsNum : function(){ var reg = /^/d+$/g; return reg.test(this); } }; JCore.apply(String.prototype,StringExtendMethod); JCore.apply(String,{//靜態方法 trim : function(str){//去掉首尾空格 return str.replace(/(^/s*)|(/s*$)/g,"");//將字符串前後空格,用空字符串替代。 } }); /*--------------------------------------------Array對象擴展----------------------------------------*/ var ArrayExtendMethod ={//去掉數組中重複的元素 strip : function(){ if(this.length<2) return [this[0]]||[]; var arr=[]; for(var i=0;i<this.length;i++){ var repeat=false; for(var j=0;jlength
;j++){ if(this[i]===arr[j]) repeat=true; } if(!repeat) arr.push(this[i]); } return arr; }, exists : function(item){ for( var i = 0 ; i < this.length ; i++ ){ if( item === this[i]) return true; } return false; }, indexOf : function(item){ for (var i = 0; i < this.length; i++){ if(this[i] === item) return i; } return -1; }, remove : function(item){ var index = this.indexOf(item); if(index != -1){ this.splice(index, 1); } return this; } }; JCore.apply(Array.prototype,ArrayExtendMethod); /*--------------------------------------------Date對象擴展----------------------------------------*/ var DateExtendMethod ={//返回時間間隔(毫秒) getElapsed : function(date) { return Math.abs((date || new Date()).getTime()-this.getTime()); } }; JCore.apply(Date.prototype,DateExtendMethod);
發佈了34 篇原創文章 · 獲贊 1 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章