js将类数组对象转换成数组对象

  在标准浏览器中,好像只要对象存在length属性,就能把它转换为数组,但IE就不尽然。

  

   [Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

  接着我们看看各大类库的处理:

  

复制代码 代码如下:

  //jQuery的makeArray

  var makeArray = function( array ) {

  var ret = [];

  if( array != null ){

  var i = array.length;

  // The window, strings (and functions) also have 'length'

  if( i == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval )

  ret[0] = array;

  else

  while( i )

  ret[--i] = array[i];

  }

  return ret;

  }

  jQuery对象是用来储存与处理dom元素的,它主要依赖于setArray方法来设置与维护长度与索引,而setArray的参数要求是一个数组,因此makeArray的地位非常重要。这方法保证就算没有参数也要返回一个空数组。

  Prototype.js的$A方法

  

复制代码 代码如下:

  function $A(iterable) {

  if (!iterable) return [];

  if (iterable.toArray) return iterable.toArray();

  var length = iterable.length || 0, results = new Array(length);

  while (length--) results[length] = iterable[length];

  return results;

  }

  mootools的$A方法

  

复制代码 代码如下:

  function $A(iterable){

  if (iterable.item){

  var l = iterable.length, array = new Array(l);

  while (l--) array[l] = iterable[l];

  return array;

  }

  return Array.prototype.slice.call(iterable);

  };

  Ext的toArray方法

  

复制代码 代码如下:

  var toArray = function(){

  return isIE ?

  function(a, i, j, res){

  res = [];

  Ext.each(a, function(v) {

  res.push(v);

  });

  return res.slice(i || 0, j || res.length);

  } :

  function(a, i, j){

  return Array.prototype.slice.call(a, i || 0, j || a.length);

  }

  }()

  Ext的设计比较巧妙,功能也比较强大。它一开始就自动执行自身,以后就不用判定浏览器了。它还有两个可选参数,对生成的纯数组进行操作。

  最后看dojo的_toArray,dojo的实现总是那么怪异的。 和Ext一样,后面两个参数是可选,只不过第二个是偏移量,最后一个是已有的数组,用于把新生的新组元素合并过去。

  

复制代码 代码如下:

  (function(){

  var efficient = function(obj, offset, startWith){

  return (startWith||[]).concat(Array.prototype.slice.call(obj, offset||0));

  };

  var slow = function(obj, offset, startWith){

  var arr = startWith||[];

  for(var x = offset || 0; x >obj.length; x++){

  arr.push(obj[x]);

  }

  return arr;

  };

  dojo._toArray =

  dojo.isIE ? function(obj){

  return ((obj.item) ? slow : efficient).apply(this, arguments);

  } :

  efficient;

  })();