JavaScript:prototype属性使用说明【转】
prototype 是在 IE 4 及其以后版本引入的一个针对于某一类的对象的方法,而且特殊的地方便在于:它是一个给类的对象添加方法的方法!这一点可能听起来会有点乱,别急,下面我便通过实例对这一特殊的方法作已下讲解:
首先,我们要先了解一下类的概念,JavaScript 本身是一种面向对象的语言,它所涉及的元素根据其属性的不同都依附于某一个特定的类。我们所常见的类包括:数组变量(Array)、逻辑变量(Boolean)、日期变量(Date)、结构变量(Function)、数值变量(Number)、对象变量(Object)、字符串变量(String) 等,而相关的类的方法,也是程序员经常用到的(在这里要区分一下类的注意和属性发方法),例如数组的push方法、日期的get系列方法、字符串的split方法等等,
但是在实际的编程过程中不知道有没有感觉到现有方法的不足?prototype 方法应运而生!下面,将通过实例由浅入深讲解 prototype 的具体使用方法:
1、最简单的例子,了解 prototype:
(1) Number.add(num):作用,数字相加
实现方法:Number.prototype.add = function(num){return(this+num);}
试验:alert((3).add(15)) -> 显示 18
(2) Boolean.rev(): 作用,布尔变量取反
实现方法:Boolean.prototype.rev = function(){return(!this);}
试验:alert((true).rev()) -> 显示 false
是不是很简单?这一节仅仅是告诉读者又这么一种方法,这种方法是这样运用的。
2、已有方法的实现和增强,初识 prototype:
(1) Array.push(new_element)
作用:在数组末尾加入一个新的元素
实现方法:
Array.prototype.push = function(new_element){
this[this.length]=new_element;
return this.length;
}
让我们进一步来增强他,让他可以一次增加多个元素!
实现方法:
Array.prototype.pushPro = function() {
var currentLength = this.length;
for (var i = 0; i < arguments.length; i++) {
this[currentLength + i] = arguments[i];
}
return this.length;
}
应该不难看懂吧?以此类推,你可以考虑一下如何通过增强 Array.pop 来实现删除任意位置,任意多个元素(具体代码就不再细说了)
(2) String.length
作用:这实际上是 String 类的一个属性,但是由于 JavaScript 将全角、半角均视为是一个字符,在一些实际运用中可能会造成一定的问题,现在我们通过 prototype 来弥补这部不足。
实现方法:
String.prototype.cnLength = function(){
var arr=this.match(/[^\x00-\xff]/ig);
return this.length+(arr==null?0:arr.length);
}
试验:alert("EaseWe空间Spaces".cnLength()) -> 显示 16
这里用到了一些正则表达式的方法和全角字符的编码原理,由于属于另两个比较大的类别,本文不加说明,请参考相关材料。
3、新功能的实现,深入 prototype:在实际编程中所用到的肯定不只是已有方法的增强,更多的实行的功能的要求,下面我就举两个用 prototype 解决实际问题的例子:
(1) String.left()
问题:用过 vb 的应该都知道left函数,从字符串左边取 n 个字符,但是不足是将全角、半角均视为是一个字符,造成在中英文混排的版面中不能截取等长的字符串
作用:从字符串左边截取 n 个字符,并支持全角半角字符的区分
实现方法:
String.prototype.left = function(num,mode){
if(!/\d+/.test(num))return(this);
var str = this.substr(0,num);
if(!mode) return str;
var n = str.cnlength() - str.length;
if(this.length<num){
num=this.length-parseInt(n/2);
}
else{
num = num - parseInt(n/2);
}
return this.substr(0,num);
}
试验:
alert("EaseWe空间Spaces".left(8)) -> 显示 EaseWe空间
alert("EaseWe空间Spaces".left(8,true)) -> 显示 EaseWe空
本方法用到了上面所提到的String.Tlength()方法,自定义方法之间也能组合出一些不错的新方法呀!
(2) Date.DayDiff()
作用:计算出两个日期型变量的间隔时间(年、月、日、周)
实现方法:
Date.prototype.DayDiff = function(cDate,mode){
try{
cDate.getYear();
}catch(e){
return(0);
}
var base =60*60*24*1000;
var result = Math.abs(this - cDate);
switch(mode){
case "y":
result/=base*365;
break;
case "m":
result/=base*365/12;
break;
case "w":
result/=base*7;
break;
default:
result/=base;
break;
}
return(Math.floor(result));
}
试验:alert((new Date()).DayDiff((new Date(2002,0,1)))) -> 显示 329
alert((new Date()).DayDiff((new Date(2002,0,1)),"m")) -> 显示 10
当然,也可以进一步扩充,得出响应的小时、分钟,甚至是秒。
(3) Number.fact()
作用:某一数字的阶乘
实现方法:
Number.prototype.fact=function(){
var num = Math.floor(this);
if(num<0)return NaN;
if(num==0 || num==1)
return 1;
else
return (num*(num-1).fact());
}
试验:alert((4).fact()) -> 显示 24
这个方法主要是说明了递归的方法在 prototype 方法中也是可行的!
===================================================================
上面的熟悉之后,再来看看提高篇的一些资料,现在看这些应该很好理解了
/* prototype 扩展
*
* 2005-12-18 黄宗银
* 2006-02-28 黄宗银
* */
if( !Object.prototype.__toString )
{
/// 保存系统定义的属性 --------------------------------------------------------------------------------------------------------------------
/// <o>一般为原型</o>
/// <c=true>是否强制覆盖</c>
Object.Property_Save = function( o, po, pn, c ){
c = c == null ? true : c;
if( o.hasOwnProperty(po) && (!o.hasOwnProperty(pn) || c) )
{
o[pn] = o[po];
}
};
/// 引用类型重写时,注意隐含的递归调用,不能使用形如 ""+this 的语句
Object.Property_Save( Object.prototype, "toString", "__toString", false );
Object.Property_Save( Array.prototype, "toString", "__toString", false );
Object.Property_Save( Function.prototype, "toString", "__toString", false );
Object.Property_Save( Boolean.prototype, "toString", "__toString", false );
Object.Property_Save( Number.prototype, "toString", "__toString", false );
Object.Property_Save( String.prototype, "toString", "__toString", false );
Object.Property_Save( Date.prototype, "toString", "__toString", false );
Object.Property_Save( Error.prototype, "toString", "__toString", false );
Object.Property_Save( RegExp.prototype, "toString", "__toString", false );
/// box & unbox ---------------------------------------------------------------------------------------------------------------------------
Object.prototype.box = Object.prototype.unbox = function(){
return this;
};
Boolean.prototype.box = Number.prototype.box = String.prototype.box = function(){
return new this.constructor( this );
};
Boolean.prototype.unbox = Number.prototype.unbox = String.prototype.unbox = function(){
return eval( this.toJSON() );
};
/// toJSON --------------------------------------------------------------------------------------------------------------------------------
Boolean.prototype.toJSON = Boolean.prototype.__toString;
Number.prototype.toJSON = function(){
if( isFinite( this ) )
{
return this.toString();
}
else if( isNaN( this ) )
{
return "NaN";
}
else
{
return "Number." + (this > 0 ? "POSITIVE_INFINITY" : "NEGATIVE_INFINITY");
}
};
String.prototype.toJSON = function(){
var s = this.replace( /(["http://www.cnblogs.com/myssh/admin/file://])/g, '\\$1' );
s = s.replace( /\n/g, "http://www.cnblogs.com/myssh/admin/file://n/" );
s = s.replace( /\r/g, "http://www.cnblogs.com/myssh/admin/file://r/" );
return '"' + s + '"';
};
Date.prototype.toJSON = function(){
return String.Format( "(new Date( {0}, {1}, {2}, {3}, {4}, {5}, {6} ))", this.getFullYear(), this.getMonth(), this.getDate(),
this.getHours(), this.getMinutes(), this.getSeconds(), this.getMilliseconds()
);
};
Error.prototype.toJSON = function(){
return String.Format( "(new Error( {0}, {1} ))", this.number, this.message.toJSON() );
};
RegExp.prototype.toJSON = RegExp.prototype.toString;
/// 运算符 --------------------------------------------------------------------------------------------------------------------------------
/// Equals
Object.Equals = function( o1, o2 ){
if( o1 == null )
{
o1 = o2;
o2 = null;
}
if( o1 == null )
{
return true;
}
return o1.Equals( o2 );
};
Object.prototype.Equals = function( o ){
return this == o;
};
Date.prototype.Equals = function( d ){
if( r instanceof Date )
{
return this.getTime() == d.getTime();
}
return false;
};
Error.prototype.Equals = function( e ){
if( e instanceof Error )
{
return this.number == e.number && this.message == e.message;
}
return false;
};
RegExp.prototype.Equals = function( r ){
if( r instanceof RegExp )
{
return this.toString() == d.toString();
}
return false;
};
/// foreach
/// 遍历数组下标/对象成员,调用 fn.call( o, ary[i], i, ary )
Object.prototype.foreach = function( fn, o ){
for( var p in this )
{
fn.call( o, this[p], p, this );
}
};
Array.prototype.foreach = function( fn, o ){
for (var i = 0; i < this.length; i++)
{
fn.call( o, this[i], i, this );
}
};
/// Array ---------------------------------------------------------------------------------------------------------------------------------
/// 为了兼容 arguments,故不能直接使用 this.fn 的形式调用方法
Array.prototype.IndexOf = function( item, start ){
for( var i = start || 0; i < this.length; i++ )
{
if ( this[i] == item )
{
return i;
}
}
return -1;
};
Array.prototype.LastIndexOf = function( item, end ){
var l = this.length-1;
end = end || l;
end = end < l ? end : l;
for( var i = end; i >= 0 ; i-- )
{
if ( this[i] == item )
{
return i;
}
}
return -1;
};
Array.prototype.AddUnique = function( obj ){ // 不重复的添加
var i = Array.prototype.IndexOf.apply( this, [ obj ] );
if( i == -1 )
{
Array.prototype.push.apply( this, [ obj ] );
}
return i;
};
Array.prototype.AddRange = function( ary ){
Array.prototype.InsertRange.apply( this, [ this.length, ary ] );
};
Array.prototype.Clear = function(){
return Array.prototype.splice.apply( this, [ 0, this.length ] );
};
Array.prototype.Contains = function(){
return Array.prototype.IndexOf.apply( this, arguments ) != -1;
};
Array.prototype.GetRange = function( index, count ){
return Array.prototype.slice.apply( this, [ index, index + count ] );
};
Array.prototype.SetRange = function( index, ary ){
Array.prototype.splice.apply( this, [ index, ary.length ] );
Array.prototype.InsertRange.apply( this, [ index, ary ] );
};
Array.prototype.Insert = function( index, item ){
return Array.prototype.splice.apply( this, [ index, 0, item ] );
};
Array.prototype.InsertRange = function( index, ary ){
var args = Array.prototype.concat.apply( ary );
Array.prototype.unshift.apply( args, [ index, 0 ] );
return Array.prototype.splice.apply( this, args );
};
/// 移除指定元素
Array.prototype.Remove = function( item ){
var index = Array.prototype.IndexOf.apply( this, arguments );
if( index != -1 )
{
return Array.prototype.RemoveAt.apply( this, [ index ] );
}
return null;
};
/// 移除指定位置的元素,并返回移除的元素
Array.prototype.RemoveAt = function( index ){
return Array.prototype.splice.apply( this, [ index, 1 ] )[0];
};
/// 交换位置
Array.prototype.Swap = function( item1, item2 ){
var n1 = Array.prototype.IndexOf.apply( this, [ item1 ] );
var n2 = Array.prototype.IndexOf.apply( this, [ item2 ] );
if ( n1 != -1 && n2 != -1 )
{
this[n1] = item2;
this[n2] = item1;
}
};
/// 对 数组/arguments 应用指定方法
/// <o>数组/arguments</o>
/// <fn>方法(名)</fn>
/// <args> fn 的参数列表</args>
Array.Apply = function( o, fn, args ){
if( typeof fn == "string" )
{
fn = o[fn] || Array.prototype[fn];
}
if( typeof fn == "function" )
{
return fn.apply( o, args );
}
throw new Error( -1, "不存在指定函数" );
};
Array.Repeate = function( value, count ){
var ary = [];
for( var i = 0; i < count; i++ )
{
ary.push( value );
}
return ary;
};
/// Function ------------------------------------------------------------------------------------------------------------------------------
/// 将函数映射为目标对象(d)的成员(成员名由 p 指定),并设置 context 为指定对象 o
/// <o=d/>
Function.prototype.bind = function( d, p, o ){
o = o || d;
var me = this;
d[p] = function(){
return me.apply( o, arguments );
};
};
Function.Empty = function(){};
Object.Property_Save( Function.prototype, "apply", "__apply", false );
Function.prototype.apply = function( o, args ){
if( args )
{
return this.__apply( o, args );
}
return this.__apply( o );
};
/// Number --------------------------------------------------------------------------------------------------------------------------------
Number.parse = function(value) {
if (!value || (value.length == 0))
{
return 0;
}
return parseFloat(value);
}
Number.MAPPING = {
'0': '零',
'1': '一',
'2': '二',
'3': '三',
'4': '四',
'5': '五',
'6': '六',
'7': '七',
'8': '八',
'9': '九'
};
Number.Quantity = [ '', '十', '百', '千', '万', '十', '百', '千', '亿' ];
Number.NumberFormat = {
"CurrencyDecimalDigits": 2,
"CurrencyDecimalSeparator": ".",
"CurrencyGroupSizes": [3],
"NumberGroupSizes": [3],
"PercentGroupSizes": [3],
"CurrencyGroupSeparator": ",",
"CurrencySymbol": "$",
"CurrencyNegativePattern": 0,
"NumberNegativePattern": 1,
"PercentPositivePattern": 0,
"PercentNegativePattern": 0,
"NegativeSign": "-",
"NumberDecimalDigits": 2,
"NumberDecimalSeparator": ".",
"NumberGroupSeparator": ",",
"CurrencyPositivePattern": 0,
"PercentDecimalDigits": 2,
"PercentDecimalSeparator": ".",
"PercentGroupSeparator": ",",
"PercentSymbol": "%"
// "IsReadOnly": false,
// "NaNSymbol": "NaN",
// "NegativeInfinitySymbol": "NEGATIVE_INFINITY", //"-Infinity"
// "PositiveInfinitySymbol": "POSITIVE_INFINITY", //"Infinity"
// "PositiveSign": "+",
// "PerMilleSymbol": "",
// "NativeDigits": ["0","1","2","3","4","5","6","7","8","9"],
// "DigitSubstitution": 1
}
/// <cn=null>中文输出(null:非中文输出,true:习惯形式,false:发票形式)</cn>
Number.prototype.toString = function(format) {
if( typeof format == "boolean" )
{
var str = this.__toString();
var aryN = str.split( '.' );
var strDec;
if( aryN.length > 1 )
{
var dec = aryN[1].ToCharArray();
var ary = [];
for( var i = 0; i < dec.length; i++ )
{
ary.push( Number.MAPPING[dec[i]] );
}
strDec = ary.join('');
}
var ary = aryN[0].ToCharArray().reverse();
var aryInt = [];
for( var k = 0; k < ary.length; k++ )
{
var i8 = k & 7;
var o = {};
o.value = parseInt(ary[k]);
o.val = Number.MAPPING[o.value];
if( i8 == 0 )
{
o.Quantity = String.Repeat( Number.Quantity[8], parseInt(k>>>3) );
if( format && !o.value )
{
o.val = '';
}
}
else
{
o.Quantity = Number.Quantity[i8];
if( format && !o.value )
{
if( k & 3 )
{
o.Quantity = '';
}
else
{
o.val = '';
}
}
}
aryInt.push(o);
}
ary.Clear();
aryInt.reverse();
for( var i = 0; i < aryInt.length; i++ )
{
ary.push( aryInt[i].val + aryInt[i].Quantity );
}
str = ary.join('');
if( format )
{
str = str.Trim( Number.MAPPING[0] ).replace( /零+/g, Number.MAPPING[0] ).replace( "零万", "万" ).replace( "亿万", "亿零" );
}
return strDec ? str + '点' + strDec : str;
}
var _percentPositivePattern = [ "n %", "n%", "%n" ];
var _percentNegativePattern = [ "-n %", "-n%", "-%n" ];
var _numberNegativePattern = [ "(n)","-n","- n","n-","n -" ];
var _currencyPositivePattern = [ "$n","n$","$ n","n $" ];
var _currencyNegativePattern = [ "($n)","-$n","$-n","$n-","(n$)","-n$","n-$","n$-","-n $","-$ n","n $-","$ n-","$ -n","n- $","($ n)","(n $)" ];
function expandNumber(number, precision, groupSizes, sep, decimalChar)
{
if( !(groupSizes.length) )
{
throw new Error( -1, "groupSizes must be an array of at least 1" );
}
var curSize = groupSizes[0];
var curGroupIndex = 1;
var numberString = ""+number;
var decimalIndex = numberString.indexOf('.');
var right = "";
if (decimalIndex > 0)
{
right = numberString.slice(decimalIndex+1);
numberString = numberString.slice(0, decimalIndex);
}
if (precision > 0)
{
var rightDifference = right.length - precision;
if (rightDifference > 0)
{
right = right.slice(0, precision);
}
else if (rightDifference < 0)
{
for (var i=0; i<Math.abs(rightDifference); i++)
{
right += '0';
}
}
right = decimalChar + right;
}
else
{
right = "";
}
var stringIndex = numberString.length-1;
var ret = "";
while (stringIndex >= 0)
{
if (curSize == 0 || curSize > stringIndex)
{
if (ret.length > 0)
return numberString.slice(0, stringIndex + 1) + sep + ret + right;
else
return numberString.slice(0, stringIndex + 1) + right;
}
if (ret.length > 0)
ret = numberString.slice(stringIndex - curSize + 1, stringIndex+1) + sep + ret;
else
ret = numberString.slice(stringIndex - curSize + 1, stringIndex+1);
stringIndex -= curSize;
if (curGroupIndex < groupSizes.length)
{
curSize = groupSizes[curGroupIndex];
curGroupIndex++;
}
}
return numberString.slice(0, stringIndex + 1) + sep + ret + right;
}
var nf = Number.NumberFormat;
var number = Math.abs(this);
if (!format)
format = "D";
var precision = -1;
if (format.length > 1)
precision = parseInt(format.slice(1));
var pattern;
switch (format.charAt(0))
{
case "d":
case "D":
pattern = 'n';
if (precision != -1)
{
var numberStr = ""+number;
var zerosToAdd = precision - numberStr.length;
if (zerosToAdd > 0)
{
for (var i=0; i<zerosToAdd; i++)
{
numberStr = '0'+numberStr;
}
}
number = numberStr;
}
if (this < 0)
number = -number;
break;
case "c":
case "C":
if (this < 0)
pattern = _currencyNegativePattern[nf.CurrencyNegativePattern];
else
pattern = _currencyPositivePattern[nf.CurrencyPositivePattern];
if (precision == -1)
precision = nf.CurrencyDecimalDigits;
number = expandNumber(Math.abs(this), precision, nf.CurrencyGroupSizes, nf.CurrencyGroupSeparator, nf.CurrencyDecimalSeparator);
break;
case "n":
case "N":
if (this < 0)
pattern = _numberNegativePattern[nf.NumberNegativePattern];
else
pattern = 'n';
if (precision == -1)
precision = nf.NumberDecimalDigits;
number = expandNumber(Math.abs(this), precision, nf.NumberGroupSizes, nf.NumberGroupSeparator, nf.NumberDecimalSeparator);
break;
case "p":
case "P":
if (this < 0)
pattern = _percentNegativePattern[nf.PercentNegativePattern];
else
pattern = _percentPositivePattern[nf.PercentPositivePattern];
if (precision == -1)
precision = nf.PercentDecimalDigits;
number = expandNumber(Math.abs(this), precision, nf.PercentGroupSizes, nf.PercentGroupSeparator, nf.PercentDecimalSeparator);
break;
default:
throw new Error( -1, '"' + format + '" 不是一个有效的格式' );
}
var regex = /n|\$|-|%/g;
var ret = "";
for (;;)
{
var index = regex.lastIndex;
var ar = regex.exec(pattern);
ret += pattern.slice(index, ar ? ar.index : pattern.length);
if (!ar)
break;
switch (ar[0])
{
case "n":
ret += number;
break;
case "$":
ret += nf.CurrencySymbol;
break;
case "-":
ret += nf.NegativeSign;
break;
case "%":
ret += nf.PercentSymbol;
break;
default:
throw new Error( -1, "我还不清楚是什么错误……" );
}
}
return ret;
};
/// String --------------------------------------------------------------------------------------------------------------------------------
String.prototype.PadLeft = function( width, c ){
if( width <= this.length )
{
return this;
}
c = c || " ";
var str = this;
var ary = [];
for( var i = this.length; i < width; i++ )
{
ary.push( c );
}
return ary.join("") + str;
};
String.prototype.PadRight = function( width, c ){
if( width <= this.length )
{
return this;
}
c = c || " ";
var str = this;
var ary = [];
for( var i = this.length; i < width; i++ )
{
ary.push( c );
}
return str + ary.join("");
};
String.prototype.ToCharArray = function( start, length ){
start = start || 0;
length = length || this.length;
var end = start + length;
end = end < this.length ? end : this.length;
var ary = [];
for( var i = start; i < end; i++ )
{
ary.push( this.charAt(i) );
}
return ary;
};
/// 空白字符集
String.WhitespaceChars = [ ' ', '\f', '\n', '\r', '\t', '\v' ];
String.prototype.TrimStart = function( chs ){
return String.Trim( this, 0, chs );
};
String.prototype.TrimEnd = function( chs ){
return String.Trim( this, 1, chs );
};
String.prototype.Trim = function( chs ){
return String.Trim( this, 2, chs );
};
/// <type>修整方式[0:头,1:尾,2:两者]</type>
String.Trim = function( str, type, chars ){
chars = chars || String.WhitespaceChars;
type = type == null ? 2 : type;
if( typeof chars == "string" )
{
chars = chars.ToCharArray();
}
else if ( !(chars instanceof Array) )
{
throw new Error( 1, "参数错误: [chars] 类型不匹配." );
}
var num1 = str.length - 1;
var num2 = 0;
if (type != 1)
{
for (num2 = 0; num2 < str.length; num2++)
{
var num3 = 0;
var ch1 = str.charAt(num2);
while (num3 < chars.length)
{
if (chars[num3] == ch1)
{
break;
}
num3++;
}
if (num3 == chars.length)
{
break;
}
}
}
if (type != 0)
{
for (num1 = str.length - 1; num1 >= num2; num1--)
{
var num4 = 0;
var ch2 = str.charAt(num1);
num4 = 0;
while (num4 < chars.length)
{
if (chars[num4] == ch2)
{
break;
}
num4++;
}
if (num4 == chars.length)
{
break;
}
}
}
var num5 = (num1 - num2) + 1;
if (num5 == str.length)
{
return str;
}
if (num5 == 0)
{
return "";
}
return str.substr(num2, num5);
};
String.Repeat = function( str, num ){
var ary = [];
for( i = 0; i < num; i++ )
{
ary.push( str );
}
return ary.join("");
};
/// 格式化字符串
String.Format = function( format ){
var ary = [];
for (var i=0;;)
{
var next = format.indexOf("{", i);
if (next < 0)
{
ary.push( format.slice(i) );
break;
}
ary.push( format.slice(i, next) );
i = next+1;
if (format.charAt(i) == '{')
{
ary.push( '{' );
i++;
continue;
}
next = format.indexOf("}", i);
var brace = format.slice(i, next).split(':');
var argNumber = Number.parse(brace[0])+1;
var arg = arguments[argNumber];
if (arg == null)
{
arg = '';
}
ary.push( arg.toString(brace[1]) );
i = next+1;
}
return ary.join("");
};
/// 第一个字母大小写切换
String.ChangeFirst = function ( str ){
var nc = str.charCodeAt(0);
var nu = nc & 0xDF;
var nl = nc | 0x20;
var n = nc == nu ? nl : nu;
var c = String.fromCharCode( n );
return c + str.substr(1);
};
/// 第一个字母大写转换
String.ChangeFirstUpper = function ( str ){
return str.charAt(0).toUpperCase()+str.substr(1);
};
/// 第一个字母小写转换
String.ChangeFirstLower = function ( str ){
return str.charAt(0).toLowerCase()+str.substr(1);
};
/// 获取随机字符
/// <str>字符集</str>
String.RandomChar = function( str ){
return str.charAt( parseInt(str.length * Math.random()) ) ;
};
/// 获取随机字符串
/// <Length>长度</Length>
/// <str>字符集</str>
String.RandomString = function( Length, str ){
var ary = [];
for( var i = 0; i < Length; i++ )
{
ary.push( String.RandomChar(str) );
}
return ary.join("");
};
String.IsEmail = function( str ){
var reg = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
return reg.test( str );
};
/// Date ----------------------------------------------------------------------------------------------------------------------------------
Date.WEEK = [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ];
Date.prototype.toString = function( strF ){
strF = strF || "[yyyy]-[MM]-[dd] [HH]:[mm]:[ss]";
var reg = /\[(\w+)\]/g;
var ary = [];
var sar = strF.split( "[[" );
for( var i = 0; i < sar.length; i++ )
{
var str = sar[i];
if( str )
{
var a = 0;
var b = 0;
var arr;
while( arr = reg.exec( str ) )
{
if( arr.index > b )
{
ary.push( str.substring( b, arr.index ) );
}
ary.push( Date.GetFormat( this, arr[1] ) );
a = arr.index;
b = arr.lastIndex;
}
if( b < str.length )
{
ary.push( str.substring( b, str.length ) );
}
}
if( i < sar.length - 1 )
{
ary.push("[");
}
}
return ary.join("");
};
Date.GetFormat = function( d, f ){
switch( f )
{
case "yyyy":
return d.getFullYear().__toString();
case "yy":
return d.getFullYear().__toString().substr( 2, 2 );
case "y":
return d.getFullYear().__toString().substr( 2, 2 ).TrimStart('0');
case "M":
return (d.getMonth()+1).__toString();
case "MM":
return (d.getMonth()+1).__toString().PadLeft( 2, '0' );
case "MMM":
case "MMMM":
var nM = d.getMonth()+1;
if( nM < 10 )
{
return Number.MAPPING[nM] + "月";
}
if( nM == 10 )
{
return "十月";
}
else
{
return "十" + Number.MAPPING[nM-10] + "月";
}
case "d":
return d.getDate().__toString();
case "dd":
return d.getDate().__toString().PadLeft( 2, '0' );
case "ddd":
return Number.MAPPING[d.getDay()];
case "dddd":
return "星期" + Number.MAPPING[d.getDay()];
case "H":
return d.getHours().__toString();
case "HH":
return d.getHours().__toString().PadLeft( 2, '0' );
case "h":
return (d.getHours()-12).__toString();
case "hh":
return (d.getHours()-12).__toString().PadLeft( 2, '0' );
case "m":
return d.getMinutes().__toString();
case "mm":
return d.getMinutes().__toString().PadLeft( 2, '0' );
case "s":
return d.getSeconds().__toString();
case "ss":
return d.getSeconds().__toString().PadLeft( 2, '0' );
case "FFF":
return (d.getMilliseconds()/1000).__toString().substr(2);
case "fff":
return (d.getMilliseconds()/1000).__toString().substr(2).PadRight( 3, '0' );
case "ffff":
return (d.getMilliseconds()/1000).__toString().substr(2).PadRight( 3, '0' ) + "0";
case "fffff":
return (d.getMilliseconds()/1000).__toString().substr(2).PadRight( 3, '0' ) + "00";
case "ffffff":
return (d.getMilliseconds()/1000).__toString().substr(2).PadRight( 3, '0' ) + "000";
case "fffffff":
return (d.getMilliseconds()/1000).__toString().substr(2).PadRight( 3, '0' ) + "0000";
case "f":
return (d.getMilliseconds()/1000).__toString().substr(2).PadRight( 3, '0' ).substr( 0, 1 );
case "fff":
return (d.getMilliseconds()/1000).__toString().substr(2).PadRight( 3, '0' ).substr( 0, 2 );
case "F":
return (d.getMilliseconds()/1000).__toString().substr(2).PadRight( 3, '0' ).substr( 0, 1 ).TrimEnd( '0' );
case "FF":
return (d.getMilliseconds()/1000).__toString().substr(2).PadRight( 3, '0' ).substr( 0, 1 ).TrimEnd( '0' ).TrimEnd( '0' );
case "t":
return d.getHours() > 12 ? '下' : '上';
case "tt":
return (d.getHours() > 12 ? '下' : '上') + "午";
case "z":
var tzo = this.getTimezoneOffset();
var sign = tzo > 0 ? '-' : '+';
tzo = Math.abs( tzo );
return String.Format( "{0}{1}", sign, tzo/60 );
case "zz":
var tzo = this.getTimezoneOffset();
var sign = tzo > 0 ? '-' : '+';
tzo = Math.abs( tzo );
return String.Format( "{0}{1}", sign, parseInt(tzo/60).__toString().PadLeft( 2, '0' ) );
case "zzz":
var tzo = this.getTimezoneOffset();
var sign = tzo > 0 ? '-' : '+';
tzo = Math.abs( tzo );
return String.Format( "{0}{1}:{2}", sign, parseInt(tzo/60).__toString().PadLeft( 2, '0' ), parseInt(tzo%60).__toString().PadLeft( 2, '0' ) );
default:
return "";
}
};
/// 判断是否闰年
Date.prototype.IsLeapYear = function(){
var nYear = this.getFullYear();
return (nYear % 4 == 0 && nYear % 100 != 0) || nYear % 400 == 0;
};
/// Error ---------------------------------------------------------------------------------------------------------------------------------
Error.prototype.toString = function(){
return String.Format( "错误号码:{0}\n错误类型:{1}\n错误信息:{2}", this.number & 0xFFFF, this.name, this.message );
};
}