首页 > 代码库 > Javascript框架设计之对象数组化
Javascript框架设计之对象数组化
类数组对象是一个很好的存储结构,但是功能太弱了,为了享受纯数组的哪些便捷的方法,使用前可以做下转换,通常可以使用$.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="http://www.mamicode.com/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.call 3、提供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框架设计之对象数组化
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。