JS中的类数组以及类数组转数组的方法

JS中类数组转数组的方法(ArrayLike)

1、首先我们要清楚什么是类数组(ArrayLike)
  • 拥有length属性,其它属性(索引)为非负整数(对象中的索引会被当做字符串来处理,这里你可以当做是个非负整数串来理解)
  • 不具有数组的所有方法
2、JavaScript中常见的类数组
  • arguments对象
  • DOM方法返回结果(getElementsByTagName()、getElementsByClassName()…)都是类数组
3、判断一个对象是否为类数组
function isArrayLike(obj) {
    if (obj &&                                // obj is not null, undefined, etc. =>obj不为空
        typeof obj === 'object' &&            // obj is an object=>obj是一个对象
        isFinite(obj.length) &&               // obj.length is a finite number=>obj的长度是一个有限数字
        obj.length >= 0 &&                    // obj.length is non-negative=>obj的长度是一个非负数字
        obj.length===Math.floor(obj.length) &&  // obj.length is an integer=>obj的长度是一个正数
        obj.length < 4294967296)              // obj.length < 2^32=>obj的长度小于2^32幂
        return true;                        // Then obj is array-like =>obj是一个类数组
    else
        return false;                       // Otherwise it is not =>obj不是一个类数组
}
4、如何确定这个对象是一个数组
  • 第一种方式:通过constructor来判断他的所属类是不是Array。如果是那么他就是一个数组,反之不是
 		console.log(ary.constructor===Array);=> true
		console.log(oLis.constructor===Array);=>false
  • 第二种方式:通过instanceof方法,检测这个对象是否为Array的一个实例
		 console.log(ary instanceof Array);=>true是数组
   		 console.log(oLis instanceof Array);=>false不是数组
  • 第三种方式:通过Object.prototype.toString.call(),检测这个对象的数据类型是否是"[object Array]"
	    console.log(Object.prototype.toString.call(ary) === "[object Array]");=>true是数组
	    console.log(Object.prototype.toString.call(oLis) === "[object Array]");=>false不是数组
  • 第四种方式:通过ES5中提供的方法isArray()
	    console.log(Array.isArray(ary));=>true是数组
	    console.log(Array.isArray(oLis));=>false不是数组
6、我们为什么要将类数组转化成数组呢?

因为类数组不具有数组的所有方法,我们将其转换成数组以后就可以调用shift,unshift,splice,slice,concat,reverse,sort…这些强大的方法,非常方便!

7、类数组转数组的方法(终于到了重点的部分)
  • Array.prototype.slice.call(arrayLike)或者[].slice.call(arrayLike)
    众所周知slice是数组才能调用的方法,但是我们通过call改变了slice中this的指向,让他指向当前的这个类数组(也就是说将类数组克隆),得到了一个和arrayLike外表一样的数组,达到了质变的过程。
    这里需要注意的一点是能调用call的只能是方法,所以我们不能用[].call(arrayLike)的方式将类数组转换成数组

//slice的内部实现
Array.prototype.slice = function(start,end){  
      var result = new Array();  
      start = start || 0;  
      end = end || this.length; //this指向调用的对象,当用了call后,能够改变this的指向,也就是指向传进来的对象,这是关键  
      for(var i = start; i < end; i++){  
           result.push(this[i]);  
      }  
      return result;  
}

顺便附上转数组的通用函数

var toArray = function(s){  
    try{  
        return Array.prototype.slice.call(s);  
    } catch(e){  
            var arr = [];  
            for(var i = 0,len = s.length; i < len; i++){  
                //arr.push(s[i]);  
                 arr[i] = s[i];     //据说这样比push快
            }  
             return arr;  
    } 
  • 也可以通过[…arrayLike]转换成数组
console.log(Object.prototype.toString.call([...arrayLike]))//=>[object Array]
  • 中间类继承
arrayLike.__proto__ = Array.prototype
8、实现两个数组的拼接
  • 数组拼接我们首先想到的方法就应该是concat(),你会发现concat()虽然能实现数组的拼接但是他不能改变原数组,我们还得用变量来接受concat()的返回值,很麻烦。
    var ary = [1, 2, 3, 4];
    var newAry = [5, 6, 7];
    console.log(ary.concat(newAry));=>[1,2,3,4,5,6,7]
    console.log(ary);=>[1,2,3,4]
  • 所以我们用下面的这个方法就可以解决上面的问题了,我们不就是要实现数组的拼接嘛,我们换一种思路想一下,拼接,无非不就是向让newAry中的每一项添加到ary的后面嘛,但是我们不能用ary.push(newAry)这个方式(不要问为什么,机制如此),所以我们可以把newAry的拆开,添加到ary中。
    var ary = [1, 2, 3, 4];
    var newAry = [5, 6, 7];
    console.log(ary.push.apply(ary, newAry));//=>7数组的长度
    console.log(ary);//=>[1,2,3,4,5,6,7]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值