面向对象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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章