/* javascript的面向对象机制 JavaScript可以像类语言那样使用,但它也有一种十分独特的表现层次。 我们已经看过了类继承、瑞士继承、寄生继承、类扩展和对象扩展。 这一等系列代码复用的模式都能来自这个一直被认为是很小、很简单的JavaScript语言。 类对象属于“硬的”。 给一个“硬的”对象添加成员的唯一的方法是建立一个新的类。 在JavaScript中,对象是“软的”。要给一个“软”对象添加成员只要简单的赋值就行了。 因为JavaScript中的类是这样地灵活,你可能会还想到更复杂的类继承。但深度继承并不合适。 浅继承则较有效而且更易表达。 */ /* method方法,可以把一个实例方法添加到一个类中。 这个将会添加一个公共方法到 Function.prototype中, 这样通过类扩展所有的函数都可以用它了。它要一个名称和一个函数作为参数。 它返回 this。 一个没有返回值的方法时,我通常都会让它返回this。这样可以形成链式语句。 */ Function.prototype.method = function (name, func){ this.prototype[name] = func; return this; }; /* 它会指出一个类是继承自另一个类的。它必须在两个类都定义完了之后才能定义,但要在方法继承之前调用。 我们扩展 Function类。我们加入一个 parent类的实例并将它做为新的prototype。 我们也必须修正constructor字段,同时我们加入uber方法。 uber方法将会在自己的prototype中查找某个方法。这个是寄生继承或类扩展的一种情况。 如果我们是类继承,那么我们要找到parent的prototype中的函数。 return语句调用了函数的apply方法来调用该函数,同时显示地设置this并传递参数。 参数(如果有的话)可以从arguments数组中获得。 不幸的是,arguments数组并不是一个真正的数组,所以我们又要用到apply来调用数组中的slice方法。 */ Function.method('inherits', function (parent) { var d = 0, p = (this.prototype = new parent());//当前类型扩展parent类型 this.method('uber', function uber(name) {//设置uber方法来获取父类对象 var f, r, t = d, v = parent.prototype; if (t){ while (t) { v = v.constructor.prototype; t -= 1; } f = v[name]; } else { f = p[name]; if (f == this[name]) { f = v[name]; } } d += 1; r = f.apply(this, Array.prototype.slice.apply(arguments, [1])); d -= 1; return r; }); return this; }); /* The swiss方法对每个参数进行循环。 每个名称,它都将parent的原型中的成员复制下来到新的类的prototype中。 */ Function.method('swiss', function (parent){ for (var i = 1; i < arguments.length; i += 1){ var name = arguments[i]; this.prototype[name] = parent.prototype[name]; } return this; }); var objs = new Array(); function addObject(obj){ obj.index = objs.length; objs[objs.length]=obj; } function getObject(index){ return objs[index]; } function getClassName(object){ var s=object.constructor.toString(); return s.match(/function (\w+)\(.+/)[1]; } function isUndefined(value){ return typeof(value)=='undefined'||value==null; } function isNumberType(value){ return typeof(value)=='number'; } function isStringType(value){ return typeof(value)=='string'; } function isBooleanType(value){ return typeof(value)=='boolean'; } function isFunctionType(value){ return typeof(value)=='function'; } function isObjectType(value){ return typeof(value)=='object'; } function isDateType(value){ return !isUndefined(value) && getClassName(value)=="Date"; } function isRegExpType(value){ return !isUndefined(value) && getClassName(value)=="RegExp"; } function isArrayType(value){ return !isUndefined(value) && getClassName(value)=="Array"; } //String String.prototype.equalsIgnoreCase=function(str){ if(!isStringType(str)) return false; return this.toUpperCase()===str.toUpperCase(); } String.prototype.compareTo=function(str){ if(!isStringType(str)) throw "Type Mismacth!"; var s1=this.toString(); var s2=str.toString(); if(s1===s2) return 0; else if(s1>s2) return 1; else return -1; } String.prototype.compareToIgnoreCase=function(str){ if(!isStringType(str)) throw "Type Mismacth!"; var s1=this.toUpperCase(); var s2=str.toUpperCase(); if(s1===s2) return 0; else if(s1>s2) return 1; else return -1; } String.prototype.startsWith=function(prefix){ return this.substring(0,prefix.length)==prefix; } String.prototype.endsWith=function(suffix){ return this.substring(this.length-suffix.length)==suffix; } String.prototype.concat=function(str){ return new String(this.toString()+str); } String.prototype.toCharArray=function(){ var charArr=new Array(); for(var i=0;i= 0) { if(arguments.length>3){ if(isFunctionType(onFindFunc)){ onFindFunc(pos1,sReplace.length-sFind.length); } } if ((pos1 + sFind.length) >= sSource.length) { sSource = sSource.substring(0, pos1) + sReplace; } else { sSource = sSource.substring(0, pos1) + sReplace + sSource.substring(pos1 + sFind.length, sSource.length); } pos1 = sSource.indexOf(sFind,pos1); } return sSource; } //Number Number.prototype.hashCode=function(){ //just for int,not for double return (this); } Number.prototype.equals=function(obj){ if(!isNumberType(obj)) return false; return this.toString()==obj.toString(); } Number.isNumber=function(value){ var re; // 声明变量。 re = new RegExp("^\\d*(\\.\\d*)?$","g"); // 创建正则表达式对象。 return re.test(value); } /** * 是否匹配精度 */ Number.matchs=function(value,intPart,scale,exact){ if(isNumberType(value)){ value=''+value; } var re; if(exact){ re="^\\d{"+intPart+"}"; if(scale!=0){ re+="\\.\\d{"+scale+"}$"; }else{ re+="$"; } }else{ re="^\\d{1,"+intPart+"}"; if(scale!=0){ re+="(\\.\\d{1,"+scale+"})?$"; }else{ re+="$"; } } return new RegExp(re,"g").test(value); } /** * 是否匹配模式,如###.## */ Number.matchPattern=function(value,pattern,exact){ var parts = pattern.split("."); var intPart=parts[0].length; var scale=0; if(parts.length>1){ scale=parts[1].length; } return Number.matchs(value,intPart,scale,exact); } Number.prototype.compareTo=function(obj){ if(!isNumberType(obj)) return false; return this-obj; } Number.toHexString=function(i){ return i.toString(16); } Number.toBinaryString=function(i){ return i.toString(2); } Date.prototype.hashCode=function(){ var l=this.getTime(); var s=Number.toHexString(l); var high=0; if(s.length>8) high=parseInt(s.substring(0,s.length-8),16); var low=l & 0xffffffff; return low^high; } Date.prototype.equals=function(obj){ if(!isDateType(obj)) return false; return this.getTime()==obj.getTime(); } Date.prototype.compareTo=function(obj){ if(!isDateType(obj)) return false; return (this.getTime()-obj.getTime())& 0xffffffff; } Date.prototype.addYear=function(offset){ offset=parseInt(offset); if(!isNumberType(offset)){ throw new Error("The given offset must be type of Number or Number String"); } this.setFullYear(this.getFullYear()+offset); return this; } Date.prototype.addMonth=function(offset){ offset=parseInt(offset); if(!isNumberType(offset)){ throw new Error("The given offset must be type of Number or Number String"); } this.setMonth(this.getMonth()+offset); return this; } Date.prototype.addDate=function(offset){ offset=parseInt(offset); if(!isNumberType(offset)){ throw new Error("The given offset must be type of Number or Number String"); } this.setDate(this.getDate()+offset); return this; } Date.prototype.addHours=function(offset){ offset=parseInt(offset); if(!isNumberType(offset)){ throw new Error("The given offset must be type of Number or Number String"); } this.setHours(this.getHours()+offset); return this; } Date.prototype.addMinutes=function(offset){ offset=parseInt(offset); if(!isNumberType(offset)){ throw new Error("The given offset must be type of Number or Number String"); } this.setMinutes(this.getMinutes()+offset); return this; } Date.prototype.addSeconds=function(offset){ offset=parseInt(offset); if(!isNumberType(offset)){ throw new Error("The given offset must be type of Number or Number String"); } this.setSeconds(this.getSeconds()+offset); return this; } Date.prototype.addMilliseconds=function(offset){ offset=parseInt(offset); if(!isNumberType(offset)){ throw new Error("The given offset must be type of Number or Number String"); } this.setMilliseconds(this.getMilliseconds()+offset); return this; } Date.prototype.minus=function(date,field){ if(date==null) throw new Error("null object"); if(!isDateType(date)){ throw new Error("not date type"); } var result=Math.abs(this.getTime()-date.getTime()); if(field>1){//秒 result=result/1000; } if(field>2){//分 result=result/60; } if(field>3){//时 result=result/60; } if(field>4){//天 result=result/24; } if(field>5){//月 result=result/30.4375; } if(field>6){//年 result=result/12; } return result; } /* *1毫秒 2秒 3分 4时 5天 6月 7年 年0 表示1970年1月1日0时 */ Date.prototype.trim=function(field){ if(arguments.length==0){ field=4; } if(field>0){ this.setMilliseconds(0); } if(field>1){ this.setSeconds(0); } if(field>2){ this.setMinutes(0); } if(field>3){ this.setHours(0); } if(field>4){ this.setDate(1); } if(field>5){ this.setMonth(0); } if(field>6){ this.setTime(0); } return this; } Date.getMonthDays=function(year,month){ year=parseInt(year); month=parseInt(month); if(!isNumberType(year)){ throw new Error("The given year should be typeof number or number string"); } if(!isNumberType(month)){ throw new Error("The given month should be typeof number or number string"); } if(month==1){ var date1=new Date(year,month,1); var date2=new Date(year,month+1,1); return (date2.getTime()-date1.getTime())/(1000*60*60*24); }else{ switch(month){ case 0: case 2: case 4: case 6: case 7: case 9: case 11: return 31; default: return 30; } } } /* 允许的模式标识符号如下: yyyy:年,转为正则表达式的(\[0-9]{4}) MM:月,两位数,如01,转为正则表达式的(\[0-9]{2});范围1~12 M:月,如1,11,转为正则表达式的(\[0-9]{1,2});范围1-12 dd:日,两位数,如01,转为正则表达式的(\[0-9]{2});范围1~31 d:日,如1,20,转为正则表达式的(\[0-9]{1,2});范围1~31 hh:小时,12小时制,两位数,如01,后跟AM,PM,24小时制的0点转为12AM,12点转为12PM, 转为正则表达式的(\[0-9]{2}(AM|PM));范围1~12 h:小时,12小时制,如1,11,后跟AM,PM,24小时制的0点转为12AM,12点转为12PM, 转为正则表达式的(\[0-9]{1,2}(AM|PM));范围1~12 HH:小时,24小时制,两位数,如01,转为正则表达式的(\[0-9]{2});范围0~23 H:小时,24小时制 ,如2,22,转为正则表达式的(\[0-9]{1,2});范围0~23 mm:分钟,两位数,如01;转为正则表达式的(\[0-9]{2});范围0~59 m:分钟,如1,11;转为正则表达式的(\[0-9]{1,2});范围0~59 SS:秒钟,两位数,如01;转为正则表达式的(\[0-9]{2});范围0~59 S:秒钟,如1,11;转为正则表达式的(\[0-9]{1,2});范围0~59 sss:毫秒,三位数,如001;转为正则表达式的(\[0-9]{3});范围0~999 s:毫秒,如1,11,111;转为正则表达式的(\[0-9]{1,3});范围0~999 */ var DATE_FIELD_PATTERNS=[ {name:'year',pattern:'yyyy',re:'([0-9]{4})',range:{min:0,max:9999}, setValue:function(date,value){ value=parseInt(value); if(!isNumberType(value)){ throw new Error("Invalid value"); } date.setFullYear(value); }, toChar:function(date){ return date.getFullYear().toString(); } }, {name:'year',pattern:'yy',re:'([0-9]{2})',range:{min:0,max:99}, setValue:function(date,value){ date.setYear(parseInt(value,10)); }, toChar:function(date){ return date.getYear().toString(); } }, {name:'month',pattern:'MM',re:'([0-9]{2})',range:{min:1,max:12}, setValue:function(date,value){ date.setMonth(parseInt(value-1,10)); }, toChar:function(date){ var month; return (month=date.getMonth()+1)<10?"0"+month:""+month; } }, {name:'month',pattern:'M',re:'([0-9]{1,2})',range:{min:1,max:12}, setValue:function(date,value){ date.setMonth(parseInt(value-1,10)); }, toChar:function(date){return ( date.getMonth()+1).toString(); } }, {name:'date',pattern:'dd',re:'([0-9]{2})',range:{min:1,max:31}, setValue:function(date,value){ date.setDate(parseInt(value,10)); }, toChar:function(date){ return (theDate=date.getDate())<10?"0"+theDate:""+theDate; } }, {name:'date',pattern:'d',re:'([0-9]{1,2})',range:{min:1,max:31}, setValue:function(date,value){ date.setDate(parseInt(value,10)); }, toChar:function(date){ return date.getDate().toString(); } }, {name:'hour',pattern:'HH',re:'([0-9]{2})',range:{min:0,max:23}, setValue:function(date,value){ date.setHours(parseInt(value,10)); }, toChar:function(date){ var hour; return (hour=date.getHours())<10?"0"+hour:""+hour; } }, {name:'hour',pattern:'H',re:'([0-9]{1,2})',range:{min:0,max:23}, setValue:function(date,value){ date.setHours(parseInt(value,10)); }, toChar:function(date){ return date.getHours().toString(); } }, {name:'minute',pattern:'mm',re:'([0-9]{2})',range:{min:0,max:59}, setValue:function(date,value){ date.setMinutes(parseInt(value,10)); }, toChar:function(date){ var minute; return (minute=date.getMinutes())<10?"0"+minute:""+minute; } }, {name:'minute',pattern:'m',re:'([0-9]{1,2})',range:{min:0,max:59}, setValue:function(date,value){ date.setMinutes(parseInt(value,10)); }, toChar:function(date){ return date.getMinutes().toString(); } }, {name:'second',pattern:'SS',re:'([0-9]{2})',range:{min:0,max:59}, setValue:function(date,value){ date.setSeconds(parseInt(value,10)); }, toChar:function(date){ var second; return (second=date.getSeconds())<10?"0"+second:""+second; } }, {name:'second',pattern:'S',re:'([0-9]{1,2})',range:{min:0,max:59}, setValue:function(date,value){ date.setSeconds(parseInt(value,10)); }, toChar:function(date){ return date.getSeconds().toString() } }, {name:'millisecond',pattern:'sss',re:'([0-9]{3})',range:{min:0,max:999}, setValue:function(date,value){ date.setMilliseconds(parseInt(value,10)); }, toChar:function(date){ var ms; return (ms=date.getMilliseconds())>99?""+ms:(ms>9?"0"+ms:"00"+ms); } }, {name:'millisecond',pattern:'s',re:'([0-9]{1,3})',range:{min:0,max:999}, setValue:function(date,value){ date.setMilliseconds(parseInt(value,10)); }, toChar:function(date){ return date.getMilliseconds().toString(); } } ]; function parseDatePattern(ptnStr,fields){ var ret=ptnStr; var j=0; var fieldArr=new Array(); for(var i=0;ipos){ fieldArr[k].pos+=exLength; } } fieldArr[j]={pos:pos,field:DATE_FIELD_PATTERNS[i]}; j++; }); } if(j>0){ fieldArr.sort(function(a,b){ return a.pos-b.pos; }); for(var i=0;i5 && !isUndefined(firstOption)){ options[0]=firstOption; } if(arguments.length<4||offset==null){ offset=0; } if(isUndefined(reverse)||!reverse){ for(var i=start;i<=end;i++){ options[options.length]=new Option(""+(i+offset),""+i); } }else{ for(var i=end;i>=start;i--){ options[options.length]=new Option(""+(i+offset),""+i); } } } } /* select列表工具类 */ function SelectList(sel,dumplicatable,maxSize,nullable){ this.select = sel; this.dumplicatable=arguments.length>1?dumplicatable:true; this.maxSize=arguments.length>2?maxSize:0; this.nullable=arguments.length>3?nullable:false; this.onBeforeChange=null; this.onAfterChange=null; this.onDumplicate=null; this.onOutMaxSize=null; this.onNullValue=null; } SelectList.method("insert",function(pValue,pText,pIndex){ with(this.select){ if(!this.nullable&&(pValue==null||pValue=="")){ if(this.onNullValue){ this.onNullValue(); }else{ alert("不能插入空值"); return this; } } if(!this.dumplicatable){ for(var i=0;i0 && this.maxSize<=options.length){ this.outMaxSize(); return this; } var text=arguments.length>1?(pText==null?value:pText):pValue; var index=arguments.length>2?pIndex:options.length; if(index<0){ return this.insert(pValue,text,0); } if(index>options.length){ return this.insert(pValue,text,options.length); } if(this.beforeChange("insert",null,new Option(text,pValue))){ for(var i=options.length;i>index;i--){ options[i]=options[i-1]; } options[index]=new Option(text,pValue); this.afterChange("insert",null,new Option(text,pValue)); } return this; } }); /* 列表删除方法 */ SelectList.method("remove",function(pValue){ with(this.select){ if(arguments.length==0||pValue==null){ this.removeSelect(); return this; }else if(isStringType(pValue)){ //0 1d 2 3d 4 5 //判断匹配数目 var matchCount=0; for(var i=0;i=0 && pValue0){ if(this.beforeChange("clear")){ this.select.options.length=0; this.afterChange("clear"); } } return this; }); SelectList.method("countByValue",function(value){ var matchCount=0; for(var i=0;i=selectedIndex;i--){ if(options[i].selected&&!options[i+1].selected){ options[i].swapNode(options[i+1]); } } this.afterChange("move",selectCount); } } return this; }); SelectList.method("removeSelect",function(){ with(this.select){ if(options.length==0){ return this; } var selectCount=0; for(var i=0;ithis.endDate.getTime()){ var dtTemp=this.startDate; this.startDate=this.endDate; this.endDate=dtTemp; this.reverse=true; }else{ this.reverse=false; } this.dateFields=new Array(); parseDatePattern(datePattern,this.dateFields); /*set all date field*/ this.selectArray=new Object(); for(var i=0;i=0){ for(var i=0;i