面向对象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);
原发布于面向对象Javascript核心支持代码(2009-05-13 21:31),现转于此!