標籤:nis init 子類 color mon cti htm function 載入
類數組對象是一個很好的儲存結構,但是功能太弱了,為了享受純數組的哪些便捷的方法,使用前可以做下轉換,通常可以使用$.slice.call()方法做轉換,但是舊版本的IE下的HTMLCollection、NodeList不是Object的子類,如果採用[].slice.call()方法可能會導致異常,下面是各大庫是怎麼處理的:
1、jQuery的makeArray
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title> <script src="../../common/jquery-1.9.1.min.js"></script></head><body> <script> //一般將一個對象轉換成數組需要用[].slice.call()方法來轉換,但是在舊版本的IE中HTMLCollection、NodeList不是Object的子類,是com對象 //所以無法使用[].slice.call()方法來把傳入的對象數組化,下面是jQuery相容IE舊版本的對象數組化方法 //該方法有以下保證 /* 1、不管是否傳入參數,始終返回一個數組,如果不傳參,則返回一個空數組 2、對傳入的參數(不包含length屬性、是字串、是jQuery方法的、是array的setInterval的)將他們的引用存入數組的第一項 3、如果傳入的參數符合數組化的要求,則進行數組化 */ //注意:傳入的集合必須是具有length屬性,然後集合的索引值必須是數字,也就是具有數組結構的集合,才能被轉換 var makeArray=function(array) { var ret=[]; if(array!=null) { var l=array.length; if(l==null || typeof array==="string" ||jQuery.isFunction(array) || array.setInterval) { ret[0]=array; } else { while (l) ret[--l]=array[l]; } } return ret; } alert(makeArray({length:3,0:"a",1:"b",2:"c"})[1]); </script></body></html>
2、dojo的對象數組化方法
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body> <script> /* dojo的對象數組化方法和Ext一樣,都是在一開始判斷瀏覽器類型,他的後面也有兩個參數,用於操作轉化後的數組 但是dojo後面的兩個參數,不是要截取數組的開始索引和結束索引 dojo的第一個參數是要轉換成數組的對象,第二個是位移量,第三個是已有的數組,傳回值是已有的數組和轉換後,並截取過的合并數組 */ var zc={}; isIE=true; (function(){ var efficient=function (obj,offest,startWith) { return (startWith||[]).concat([].slice.call(obj,offest || 0)); } var slow=function (obj,offest,startWith) { var arr=startWith || []; //位移量不支援負數 for(var i=offest || 0;i<obj.length;i++) { arr.push(obj[i]); } return arr; } zc.toArray=isIE?function (obj) { return slow.apply(this,arguments); }:efficient; })(); alert(zc.toArray({length:3,0:"a",1:"b",2:"c"},0,[1,2,3])); </script></body></html>
3、Ext的對象數組化方法
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body> <script> /* Ext設計的比較巧妙,在架構一載入的同時,就判斷瀏覽器的的類型,然後存到變數中,後面就不需要判斷瀏覽了, 然後根據瀏覽器的是不是IE來選擇toArray到底引用那個方法體,如果是IE瀏覽器,則吊用自訂的對象數組化方法, 如果不是則調用[].slice.call(),並通過slice方法,通過i,j參數對字串進行截取操作 */ /* 該方法有以下保證 1、如果在IE瀏覽器下執行,則則調用自訂的對象數組化方法 2、如果不再IE下,吊用[].slice.call()來進行對象數組化 3、可以提供兩個參數(start,end),用於截取指定長度的轉換後的對象數組 */ var toArray=function () { var returnisIE;//判斷瀏覽器是否是IE return returnisIE?function(a,i,j){ var length=a.length || 0,result=new Array(length); while (length--) result[length]=a[length]; return result.slice(i || 0,j|| a.length); }:function(a,i,j){ return Array.prototype.slice.call(a,i || 0,j || a.length); }; }(); var res=toArray({length:2,0:"a",1:"2"},1); alert(res) </script></body></html>
4、mootools
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body><script> /* mootools的對象數組化方法 */ /* 該方法有以下保證 1、當使用者傳入的是HTMLCollection集合是,因為老版IE的HTML節點對象是COM對象,不是Js對象的子類,所以無法使用[].slice.call()方法 使用自訂的對象數組化方法 2、如果傳入的對象不是上面的那種情況,那麼吊用[].slice.call()方法來進行對象數組化 */ function $A(array) { if(array.item) { var length=array.length || 0,result=new Array(length); while (length--) result[length]=array[length]; return result; } return Array.prototype.slice.call(array); } var res=$A({length:2,0:1,1:2});//輸出:1,2 alert(res)</script></body></html>
5、Prototype
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body><script> /* Prototype的對象轉換成數組的方法 */ /* 該方法有以下保證 1、如果不傳入參數,返回空數組 2、如果當前瀏覽器支援toArray()方法,那麼調用該對象的toArray()方法 3、如果上面兩種條件都不滿足,那麼拿到當前對象的length屬性(如果沒有給0),然後new一個具有length長度的數組,並進行賦值 */ //注意:要轉換成數組的對象的length不能大於實際元素的長度,也不能小於實際元素的長度 function $A(array){ if(!array)return []; if(array.toArray)return array.toArray(); var length=array.length || 0,results=new Array(length); while (length--) results[length]=array[length]; return results; } var result=$A({length:3,0:1,1:2,2:3}); alert(result);</script></body></html>
6、mass
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body><script>/*下面是mass的對象數組化方法 *//*該方法有以下保證:1、一開始就對瀏覽器進行區分2、如果是IE則調用自訂對戲那個數組化方法,如果不是,則使用[].slice.call3、提供start和end參數,方便對(傳入對象數組化之後的數組)進行截取4、保證start和end參數的輸入不會影響輸出結果 */isIE=true;var toArray=window.isIE?function(nodes,start,end){ var ret=[],length=nodes.length; if(end===void 0 || typeof end==="number" && isFinite(end)) { start=parseInt(start,10) || 0; end=end==void 0?length:parseInt(end,10); if(start<0) start+=length; if(end>length) end=length; if(end<0) end+=length; for(var i=start;i<end;i++) { ret[i-start]=nodes[i]; } } return ret;}:function (nodes,start,end){ return Array.prototype.slice.call(nodes,start,end);};var res=toArray({length:3,0:1,1:"a",2:"b"},0,-1);//輸出:1,a alert(res);</script></body></html>
Javascript架構設計之對象數組化