本文深入解析JavaScript中伪数组(如arguments、NodeList)与真数组的本质区别,重点分析原型链指向差异导致的方法调用报错原因,并详细介绍四种将伪数组转换为真数组的实用方法:手动遍历、slice.call、扩展运算符及Array.from,帮助开发者正确使用数组内置方法。
在JavaScript开发中,经常遇到一个常见疑问:
当函数接收多个参数时,arguments对象返回的是一个类似数组的结构。若尝试通过forEach遍历该结构进行求和,通常会抛出错误。这背后的原因究竟是什么?
(此处为幽默插科打诨,非技术内容)
具体代码示例如下:

运行上述代码后,控制台会输出错误信息。

要理解这一现象,首先需要厘清真数组与伪数组在底层实现上的本质差异。
既然arguments返回的结构看似具备数组特征,为何调用forEach会报错?
原因在于,它并非真正的数组实例,而是被称为“类数组”或“伪数组”的对象。这只是一个概念上的分类,无需被术语迷惑。
接下来,我们将深入探讨伪数组的具体定义与特征。
首先观察接收实参的arguments对象,其执行代码如下:
function fn() {
console.log(arguments);
}
fn(1,2,3,4,5)执行上述代码后的输出结果如下。

从输出可见,arguments对象虽然显示为方括号形式 [1,2,3,4,5...],但后续还包含其他非数组属性。它具备length属性,却缺失push、pop等数组内置方法,呈现出“像数组而非数组”的特征。
此外,通过观察 [[prototype]] 属性可知,arguments伪数组的原型链指向Object对象。
开发者还可以打印其他类似结构,例如通过getElementsByClassName获取的元素集合。
<div></dic>
<div></dic>
<div></dic>
<script>
var oDivs = document.getElementsByTagName("div");
console.log(oDiv);
</script>查看其输出结果:

可见:HTMLCollection 显示包含方括号 [1, 2, 3, 4, 5...],且附带其他方法;具备 length 属性,但缺失 push、pop 等数组方法,呈现类数组非数组特征。
进一步观察发现,通过标签名获取页面元素所得的伪数组,其原型指向HTMLCollection对象。
除此之外还存在其他类似结构,此处不再赘述。简而言之,伪数组具备以下核心特征:
- 具备length属性,可获取集合长度;
- 具备索引下标,可通过length属性遍历获取所有值。
- 然而,无法直接调用数组的内置方法。
对比真数组的打印结果:

可见,真数组的 __proto__ 指向Array构造函数。
既然原型不同,为何伪数组无法使用数组内置方法和属性?
基于前述分析,伪数组与真数组的原型链不同,属于不同的对象类型。真数组的原型是Array,而伪数组的原型通常指向Object或其他特定构造函数(如HTMLCollection)。这种本质差异导致伪数组无法直接调用数组方法。例如,若需使用forEach、pop等方法,必须先将伪数组转换为真数组。
接下来介绍将伪数组转换为真数组的几种常用方法:
方法一:最基础的方式。
//1.先声明一个空数组
let newArr = [];
//然后遍历伪数组
for (let i = 0; i < arguments.length; i++ ) {
//将伪数组中的值通过索引逐个添加到新数组当中。
newArr[i] = arguments[i};
}方法二:利用Array原型对象的slice方法,配合call()改变slice中的this指向。
//slice原本是数组的截取子数组的方法,这里给数组的原型对象方法slice的指向强制改成arguments
let newArr = Array.prototype.slice.call(arguments);方法三:利用ES6的扩展运算符(...)将伪数组展开并转化为真数组。
//ES6语法 let newArr=[];
let newArr = [...arguments];方法四:利用ES6提供的Array.from方法。
let newArr = Array.from(arguments);完成转换后,即可得到真正的数组实例,后续再使用forEach或其他数组方法便不会报错。
总结:
伪数组的原型通常指向Object(或特定构造函数),而真数组的原型指向Array;
伪数组本质上是键值对形式(以数字为键),真数组则是基于索引下标实现的;
伪数组可通过上述四种方式转换为真数组,从而使用forEach等数组方法;
此外,若仅需普通遍历,使用for循环即可实现,无需转换为真数组。在实际开发中,请根据具体场景酌情选择合适方案。
本文关于JavaScript中伪数组与真数组的探讨至此结束。如需了解更多相关js伪数组和真数组内容,请搜索本站历史文章或继续浏览下方的相关文章,感谢支持!