|
Javascript做面向对象开发的时候,总是会用到很多模拟面向对象特性的方法,这些方法就构成了支撑面向对象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;ilength;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(//&/;/g, '/&').replace(//>/;/g, '/>').replace(//</;/g, '/<').replace(//"/;/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);
|
|