什么是伪数组呢?
1.我们先来看看用于接受实参的方法 arguments , 执行代码如下:
function fn() {
console.log(arguments);
}
fn(1,2,3,4,5)
这里可以看到,Arguments显示的也有方括号 [1,2,3,4,5...] ,但是后面多了一些其他方法;也有length属性,但没有数组的push,pop等那些方法,像数组又不是数组
2.大家也可以去打印看看其他比如getElementsByClassName 得到的
这里可以看到,HTMLCollection显示的也有方括号 [1,2,3,4,5...] ,但是后面多了一些其他方法;也有length属性,但同样没有数组的push,pop等那些方法,像数组又不是数组
当然也还有一些其他的,这里就不一一列举了,简单说,伪数组具有以下特点:
-
拥有length属性,可以获取长度;
-
拥有角标索引,可以通过length属性遍历获取所有值。
-
但是不可以使用数组的内置方法。
-
那么我们一起看看为什么伪数组不能使用数组的内置方法和属性呢?
-
首先从上图标注的 [[prototype]]可以看到arguments伪数组的原型指向的是Object对象
再来打印真数组,
可以看到,真数组的proto指向的是Array数组
同样 从上图也可以看出 [[prototype]]可以看到通过标签名获取页面元素拿到的伪数组的原型指向的是HTMLCollection对象
至此,我们也可以看出伪数组的原型不一样,其实就是不同的对象,而数组的元素是Array,他们和真数组的本质不一样,这也是伪数组为什么不能使用数组的属性和方法的根本原因,
要使用真数组的方法比如forEach,pop等
必须把他们转化为真数组才能使用数组的各种方法。
下面来说说伪数组转真数组的方法
1 最简单的方法:先声明一个空数组,然后遍历伪数组,将伪数组中的值通过索引逐个添加到新数组当中。
2 利用Array的原型对象的slice方法,配合call()方法修改slice中this指向
slice原本是数组的截取子数组的方法,这里给数组的原型对象方法slice的指向强制改成arguments
3 利用扩展运算符(...)将伪数组转化为真数组 - ES6语法 let newArr=[];
4 利用ES6的Array.from方法
改变之后,我们就可以得到一个真正的数组,后面再使用forEach获取其他方法也就不会报错啦。
总结:
- 伪数组的原型是Object ,是真数组的原型是Array ;
- 伪数组其实是键值对的形式,真数组是基于索引下标实现的;
- 伪数组可以通过以上方式转化为真数组,进而使用数组的forEach等其他方法
当然了,如果只是普通遍历也可以用for循环来实现,不需要转真数组这么麻烦,在实际开发中大家也要酌情使用哦。