jasmine214--love

          只有當你的內心總是充滿快樂、美好的愿望和寧靜時,你才能擁有強壯的體魄和明朗、快樂或者寧靜的面容。
          posts - 731, comments - 60, trackbacks - 0, articles - 0

          js--添加自定義的擴展函數--Array 對象

          Posted on 2010-06-16 12:12 幻海藍夢 閱讀(1616) 評論(0)  編輯  收藏 所屬分類: JS

          http://www.cnblogs.com/windows7/archive/2010/05/22/1741612.html
          我們經常給 String,Function,Array 的原型加上自定義的擴展函數,比如去除字符串空格,數組排序等

          ?今天重點講下 如何給Array對象擴展

          1、直接在Array.prototype 上擴展

          2、用自己方法對數組對象進行擴展

          ?

          直接在Array.prototype上擴展,不能直接對dom對象使用(如:document.getElementsByTagName('div')得到的nodeList);

          對有潔癖的同學而言 也破了原始生態環境的 : )

          ?

          先來看下 yui操作數組的一些方法,這里我對源碼簡單剝離并改動了下

          ?

          ( function (){
          ????
          var ?YArray;

          ????YArray?
          = ? function (o,idx,arraylike){
          ????????
          var ?t? = ?(arraylike)? ? ? 2 ?:?YArray.test(o),
          ?????????l,?a,?start?
          = ?idx? || ? 0 ;
          ??????????
          if ?(t)?{
          ????????????
          try ?{
          ????????????????
          return ?Array.prototype.slice.call(o,?start); //借助Array原生方法來把aguments轉換為JS數組
          ????????????}?
          catch (e)?{
          ????????????????a?
          = ?[];
          ????????????????l?
          = ?o.length;
          ????????????????
          for ?(;?start l;?start ++ )?{
          ????????????????????a.push(o[start]);
          ????????????????}
          ????????????????
          return ?a;
          ????????????}
          ????????}?
          else ?{
          ????????????
          return ?[o];
          ????????}

          ????}

          ????YArray.test?
          = ? function (o){
          ?????????
          var ?r? = ? 0 ;?
          ????????
          if ?(o? && ?( typeof ?o? == ? ' object ' ? || typeof ?o? == ? ' function ' ))?{
          ??????????????
          if ?(Object.prototype.toString.call(o)? === ? " [object?Array] " )?{
          ????????????????r?
          = ? 1 ;?
          ????????????}?
          else ?{
          ????????????????
          try ?{
          ????????????????????
          if ?(( ' length ' ? in ?o)? && ? ! o.tagName? && ? ! o.alert? && ? ! o.apply)?{
          ????????????????????????r?
          = ? 2 ;
          ????????????????????}????
          ????????????????}?
          catch (e)?{}
          ????????????}
          ????????}
          ????????
          return ?r;
          ????}

          ????YArray.each?
          = ?(Array.prototype.forEach)? ? //先檢測瀏覽器是否已支持,若有則調用原生
          ????????
          function ?(a,?f,?o)?{?
          ????????????Array.prototype.forEach.call(a?
          || ?[],?f,?o? || ?Y);
          ????????????
          return ?YArray;
          ????????}?:
          ????????
          function ?(a,?f,?o)?{?
          ????????????
          var ?l? = ?(a? && ?a.length)? || ? 0 ,?i;
          ????????????
          for ?(i? = ? 0 ;?i? ?l;?i = i + 1 )?{
          ????????????????f.call(o?
          || ?Y,?a[i],?i,?a);
          ????????????}
          ????????????
          return ?YArray;
          ????????};

          ????YArray.hash?
          = ? function (k,?v)?{
          ????????
          var ?o? = ?{},?l? = ?k.length,?vl? = ?v? && ?v.length,?i;
          ????????
          for ?(i = 0 ;?i l;?i = i + 1 )?{
          ????????????
          if ?(k[i])?{
          ????????????????o[k[i]]?
          = ?(vl? && ?vl? > ?i)? ? ?v[i]?:? true ;
          ????????????}
          ????????}

          ????????
          return ?o;
          ????};

          ????YArray.indexOf?
          = ?(Array.prototype.indexOf)? ?
          ????????
          function (a,?val)?{
          ????????????
          return ?Array.prototype.indexOf.call(a,?val);
          ????????}?:
          ????????
          function (a,?val)?{
          ????????????
          for ?( var ?i = 0 ;?i a.length;?i = i + 1 )?{
          ????????????????
          if ?(a[i]? === ?val)?{
          ????????????????????
          return ?i;
          ????????????????}
          ????????????}
          ????????????
          return ? - 1 ; //尋找不到的情況
          ????????};

          ????YArray.numericSort?
          = ? function (a,?b)?{?
          ????????
          return ?(a? - ?b);?? //從小到大排序, return (b - a); 從大到小
          ????};


          ????YArray.some?
          = ?(Array.prototype.some)? ?
          ????????
          function ?(a,?f,?o)?{?
          ????????????
          return ?Array.prototype.some.call(a,?f,?o);
          ????????}?:
          ????????
          function ?(a,?f,?o)?{
          ????????????
          var ?l? = ?a.length,?i;
          ????????????
          for ?(i = 0 ;?i l;?i = i + 1 )?{
          ????????????????
          if ?(f.call(o,?a[i],?i,?a))?{
          ????????????????????
          return ? true ;
          ????????????????}
          ????????????}
          ????????????
          return ? false ;
          ????????};

          })();

          ? 借助Array原生方法來把aguments轉換為JS數組 的其他方法 (Dom對象不可以,只有遍歷)

          Array.apply( null ,arguments);
          [].slice.call(arguments,
          0 );
          [].splice.call(arguments,
          0 ,arguments.length);
          [].concat.apply([],arguments);
          ...


          ?

          ?YArray函數不僅可以操作數組對象也對nodeList對象進行了操作

          YArray(document.getElementsByTagName( " div " ));

          遍歷dom對象 重新組裝成一個數組 : )

          ?a? = ?[];
          ? l?
          = ?o.length;
          ?
          for ?(;?start l;?start ++ )?{
          ?????? a.push(o[start]);
          ?? }
          ?
          return ?a;


          ?YArray.each

          ?遍歷數組,如有傳入函數,每次遍歷都執行callback

          YArray.each([ 1 , 2 , 3 ], function (item){
          ???alert(item);
          // ?執行了3次,1,2,3
          });


          YArray.hash

          數組 組裝成 鍵值對 可以理解成一個json對象

          YArray.hash([ " a " , " b " ],[ 1 , 2 ]);?


          ?YArray.indexOf

          返回(想要找尋值)一樣的該值在數組的索引值

          ?

          YArray.indexOf([ 1 , 2 ], 1 )


          ?YArray.numericSort

          對數組進行排序,從小到大

          ?[ 3 ,? 1 ,? 2 ].sort(YArray.numericSort);


          YArray.some

          是否數組中的有元素通過了callBack的處理?如果有,則立馬返回true,如果一個都沒有,則返回false?

          YArray.some([ 3 ,? 1 ,? 2 ], function (el){
          ???
          return ?el? ? 4 ;?
          })


          ?

          讓我們看看 javascript?1.6 -1.8 對數組的擴展 ,并學習如何實現相同的功能

          • every
          • filter
          • forEach
          • indexOf
          • lastIndexOf
          • map
          • some
          • reduce
          • reduceRight

          ?

          				Array.prototype.every
          				

          ?

          if ?( ! Array.prototype.every)
          {
          ??Array.prototype.every?
          = ? function (fun? /* ,?thisp */ )
          ??{
          ????
          var ?len? = ? this .length? >>> ? 0 ;
          ????
          if ?( typeof ?fun? != ? " function " )
          ??????
          throw ? new ?TypeError();

          ????
          var ?thisp? = ?arguments[ 1 ];
          ????
          for ?( var ?i? = ? 0 ;?i? ?len;?i ++ )
          ????{
          ??????
          if ?(i? in ? this ? &&
          ??????????
          ! fun.call(thisp,? this [i],?i,? this ))
          ????????
          return ? false ;
          ????}

          ????
          return ? true ;
          ??};
          }

          是否數組中的每個元素都通過了callBack的處理?如果是,則返回true,如果有一個不是,則立馬返回false

          ?這和我們剛才提到的YUI種的 some 函數 很雷同 :) 功能剛好相反

          ?

          ?

          				Array.prototype.filter

          ?

          Array.prototype.filter? = ? function ?(block? /* ,?thisp? */ )?{?? // 過濾器?,添加方便,進行判斷過濾
          ???? var ?values? = ?[];
          ????
          var ?thisp? = ?arguments[ 1 ];
          ????
          for ?( var ?i? = ? 0 ;?i? ? this .length;?i ++ )
          ????????
          if ?(block.call(thisp,? this [i]))
          ????????????values.push(
          this [i]);
          ????
          return ?values;
          };


          使用方法

          var ?val = ?numbers.filter( function (t){
          ????
          return ?t? ? 5 ?;
          })
          alert(val);


          ?forEach 和 ?indexOf 和 ?some 可以參考 上面yui的代碼 ,不再重述

          lastIndexOf? 和 indexOf? 代碼相似 只是從最后開始遍歷

          ?

          下面講下 ‘ map’

          Array.prototype.map? = ? function (fun? /* ,?thisp */ )?{?
          ????
          var ?len? = ? this .length? >>> ? 0 ;
          ????
          if ?( typeof ?fun? != ? " function " )
          ??????
          throw ? new ?TypeError();

          ????
          var ?res? = ? new ?Array(len);
          ????
          var ?thisp? = ?arguments[ 1 ];
          ????
          for ?( var ?i? = ? 0 ;?i? ?len;?i ++ )?{
          ????????
          if ?(i? in ? this )
          ????????????res[i]?
          = ?fun.call(thisp,? this [i],?i,? this );
          ????}

          ????
          return ?res;
          };

          遍歷數組,執行函數,迭代數組,每個元素作為參數執行callBack方法,由callBack方法對每個元素進行處理,最后返回處理后的一個數組

          var numbers = [1, 4, 9];
          var roots = numbers.map(function(a){return a * 2});

          ?

          ?

          				Array.prototype.reduce

          ?

          ?Array.prototype.reduce? = ? function (fun? /* ,?initial */ )?{?
          ????
          var ?len? = ? this .length? >>> ? 0 ;
          ????
          if ?( typeof ?fun? != ? " function " )
          ????????
          throw ? new ?TypeError();

          ???? if ?(len? == ? 0 ? && ?arguments.length? == ? 1 )
          ????????
          throw ? new ?TypeError();

          ????
          var ?i? = ? 0 ;
          ????
          if ?(arguments.length? >= ? 2 )?{
          ????????
          var ?rv? = ?arguments[ 1 ];
          ????}?
          else ?{
          ????????
          do ?{
          ????????????
          if ?(i? in ? this )?{
          ????????????????rv?
          = ? this [i ++ ];
          ????????????????
          break ;
          ????????????}

          ???????????? if ?( ++ i? >= ?len)
          ????????????????
          throw ? new ?TypeError();
          ????????}?
          while ?( true );
          ????}

          ????
          for ?(;?i? ?len;?i ++ )?{
          ????????
          if ?(i? in ? this )
          ????????????rv?
          = ?fun.call( null ,?rv,? this [i],?i,? this );
          ????}

          ????
          return ?rv;
          };

          讓數組元素依次調用給定函數,最后返回一個值,換言之給定函數一定要用返回值?

          ?

          ?

          				Array.prototype.reduceRight

          ?

          見名故而思意,從右往左

          Array.prototype.reduceRight? = ? function (fun? /* ,?initial */ )?{?
          ????????
          var ?len? = ? this .length? >>> ? 0 ;
          ????????
          if ?( typeof ?fun? != ? " function " )
          ????????????
          throw ? new ?TypeError();
          ????????
          if ?(len? == ? 0 ? && ?arguments.length? == ? 1 )
          ????????????
          throw ? new ?TypeError();

          ????????
          var ?i? = ?len? - ? 1 ;
          ????????
          if ?(arguments.length? >= ? 2 )?{
          ????????????
          var ?rv? = ?arguments[ 1 ];
          ????????}?
          else ?{
          ????????????
          do ?{
          ????????????????
          if ?(i? in ? this )?{
          ????????????????????rv?
          = ? this [i -- ];
          ????????????????????
          break ;
          ????????????????}
          ????????????????
          if ?( -- i? ? 0 )
          ????????????????????
          throw ? new ?TypeError();
          ????????????}?
          while ?( true );
          ????????}

          ????????
          for ?(;?i? >= ? 0 ;?i -- )?{
          ????????????
          if ?(i? in ? this )
          ????????????????rv?
          = ?fun.call( null ,?rv,? this [i],?i,? this );
          ????????}
          ????????
          return ?rv;
          ????};


          除了這些,只用想用到的方法都能加到Array.prototype上

          比如常用的toString

          Array.prototype.toString? = ? function ?()?{
          ????
          return ? this .join( '' );?
          };


          還可以添加? toJson ,uniq ,compact,reverse等?

          ?? Array擴展對開發還是很有幫助滴 : )?

          主站蜘蛛池模板: 余江县| 桑日县| 平利县| 中阳县| 涞水县| 淮北市| 浑源县| 天台县| 湖口县| 邹平县| 广昌县| 内黄县| 嘉荫县| 图们市| 讷河市| 辽阳县| 中西区| 镇安县| 岗巴县| 衢州市| 乌兰浩特市| 虞城县| 赤峰市| 宝鸡市| 多伦县| 罗甸县| 玉环县| 雅江县| 溧阳市| 大足县| 吉木萨尔县| 大姚县| 都昌县| 双桥区| 博客| 航空| 循化| 昌黎县| 鞍山市| 张家港市| 武义县|