详解javascript中的类数组

文章资讯 2020-07-21 00:06:42

详解javascript中的类数组

一.什么是类数组
拥有length属性,其它属性(索引)为非负整数 (对象中的索引会被当做字符串来处理);
不具有数组所具有的方法; javascript中常见的类数组有 arguments对象和 DOM方法的返回结果。比如 document.getElementsByTagName()。
二.变成类数组的必须条件
属性要为索引(数字)属性,必须有length 属性,最好加上属性。
三.判断是否是类数组
function isLikeArray(o) {
if (typeof o === 'object' && isFinite(o.length) && o.length >= 0 && o.length < 4294967296){
// 4294967296: 2^32
return true
} else {
return false
}
}
四.类数组转换为数组
[].slice.call() 常用来将类数组转化为真正的数组
要理解其中的原理,必须了解以下几个知识点:
继承
这里的空数组是Array构造函数的实例,继承了Array.prototype的slice()方法,因此有以下关系:
[].slice === Array.prototype.slice // ture
函数的call()方法
call()是所有函数都具备的方法,其作用有两个,即:
调用函数
调用call()方法的这个函数,例如:fn.call()可以粗略的理解为fn()(暂时先不考虑参数的情况下)。
改变函数内部this指向
将函数fn内部的this指向call()方法的第一个对象参数,这么做的意义是可以使这个对象把fn这个函数(或者说方法)据为己有。
数组的slice()方法
返回一个新的数组,包含从 start 到 end (不包括该元素)的 arrayObject 中的元素。
请注意,该方法并不会修改数组,而是返回一个子数组(浅拷贝)。如果想删除数组中的一段元素,应该使用方法 Array.splice()。
例1:[].slice.call(),如果传入一个类数组
var arrayLike1 = {
0: 'a',
1: 'b',
2: 'c',
length: 3,
};
[].slice.call(arrayLike)将经历这些步骤: 让arrayLike拥有数组的slice方法,slice方法被调用,其作用目标为arrayLike1,由于没有传入其他参数,slice()默认返回所有下标的元素并返回新数组,最终得到:
var array = [].slice.call(arrayLike1);
console.log('demo========= 类数组转化为真正的数组:', array); // [a,b,c]
apply和call具有同样的作用,为什么不用apply呢?
两者的区别在于传参的形式,从第二个参数开始(都是可选参数),都会成为调用的函数的参数,call接收一个个参数,而apply接收一个由这些参数组成的数组。如果只是原封不动的转换成数组的话,用apply和call没有任何区别,如果在转换的过程中需要对slice传参,call就更合适了。
例2:
var arrayLike2 = {
0: 'a',
1: 'b',
2: 'c',
length: 3,
name: '123',
push: Array.prototype.push,
script: Array.prototype.splice,
};
arrayLike2.push('d');
var array2 = [].slice.call(arrayLike2);
console.log( array2); // [ 'a', 'b', 'c', 'd' ]
转成数组的通用函数
function toArray() {
try {
return [].slice.call(arguments);
// return Array.prototype.slice.call(arguments);
// return Array.from(arguments); //es6方法(浏览器是否支持)
} catch (e) {
var arr = [];
for (var i = 0, len = arguments.length; i < len; i++) {
//arr.push(arguments[i]);
arr[i] = arguments[i]; //据说这样比push快
}
return arr;
}
}
let newList = toArray(1, 2, 3, 4);
newList.push(5);
console.log( newList, typeof newList, Array.isArray(newList)); // [ 1, 2, 3, 4, 5 ] object true