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 );
 };
}


 

posted on 2009-06-03 21:54  ToKens  阅读(317)  评论(0编辑  收藏  举报