搜索:
首页 >> JavaScript >> Js实例技巧 >> 将各种类型或对象都转变为数组

将各种类型或对象都转变为数组

2009-12-28 来源:Ruby's Louvre 投递文章

jQuery的makeArray有其局限性(1.3.4还有bug),我自己实现了一个,不过涉及N多辅助方法。

var dom = {},
_toString = Object.prototype.toString,
_slice = Array.prototype.slice;
dom.is = function(obj,type) {
  return _toString.call(obj).match(/^\[object\s(.*)\]$/)[1] === type;
}
dom.isArray = function (obj) {
  return dom.is(obj,"Array");
}
dom.isNumber = function (obj) {
  return dom.is(obj,"Number");
}
dom.isString = function (obj) {
  return dom.is(obj,"String");
}
dom.isArrayLike =  function (obj) {//包括Array
  if(dom.isArray(obj) || obj.callee) return true;
  if(dom.is(obj,'NodeList')) return true;
  if(dom.is(obj,'HTMLCollection')) return true;
  //不能为字符串,不能为window,具有length属性
  if(dom.isNumber(obj.length) && !dom.isString(obj) && !obj.eval){
    if(obj.nextNode || obj.item)
      return true;
    var n = obj.length - 1 < 0 ? 0 : obj.length - 1 ;
    //如果是具有数字键或length属性的对象,如jQuery对象
    if(obj.hasOwnProperty(n) && obj.hasOwnProperty(0))
      return true
    return false;
  }
  return false;
}
dom.toArray = function (arr) { //把普通对象变成原生数组对象
  if(arguments.length === 0 || arr === null){
    return [];
  }else if(arr.callee){//如果是Arguments对象
    return _slice.call(arr);
  }else if(dom.isArray(arr)){//如果Array对象返回一个克隆
    return arr.concat();
  }else if(dom.isArrayLike(arr)){
    try{//jQuery对象,dom对象,el.getElementsByTagName得到的HTMLCollection
      //与el.childNodes得到的NodeList
      return _slice.call(arr);
    }catch(e){//IE用slice处理元素或节点集合会出错,只能慢慢拷贝
      var ret = [], i = arr.length;
      while (i) ret[--i] = arr[i]; //Clone数组
      return ret;
    }
  }else {//普通函数,单个元素节点,字符串,数字,window对象
    return [arr];
  }
}

早期尝试使用Ext.isIterable,不过它有点小BUG,如放一个函数进去,它会返回undefined,好歹返回false嘛,另对于用户自定义的类数组对象无法检测,残念!不过我的isArrayLike也不完美,自定义的东西随意性太大了,暂时没办法一网打尽……以后慢慢改进!

下面是测试:

[提示:你可先修改部分代码,再按运行]

 

Tags:jquery  bug  数组  对象 
相关文章
手机版 Js实例技巧 Asp之家 Aspxhome.com
闽ICP备06017341号