面向对象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);