前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
首页程序员面试题库类数组对象 arguments 与数组转换
JavaScript数组与集合

什么是类数组对象?arguments 和真数组有什么区别,怎么转换?

类数组就是有 length 和数字下标、看起来像数组但原型不是 Array.prototype 的对象。arguments 是其中最常见的一个,能用 arguments[0] 读参数,却不能调用 map、forEach。转换成真数组用 Array.from(arguments) 或 [...arguments],新代码直接用剩余参数 ...args 就不需要转换了。

前端进阶之旅 · 一题精讲更新于 2026.09.29
JavaScript#数组与集合
先看核心答案读代码示例
理解线索

`arguments` 和真数组差在哪

  1. 原型arguments 继承自 Object.prototype,所以没有 map、push 这些方法
  2. 相同的部分都有 length、都能按下标读写,arguments 在现代引擎里也能被 for...of 遍历
  3. 额外的行为非严格模式下 arguments[0] 和第一个形参是联动的,改一个另一个也变

arguments.length 是调用时实际传入的参数个数,不是函数声明的形参个数。形参个数要看 fn.length。

核心回答

先记住这个答案

类数组对象是指有 length 属性、并且用 0、1、2 这样的数字作为键的对象。它长得像数组,但原型不是 Array.prototype,所以没有 map、forEach、push 等数组方法。arguments 是函数内部自动提供的类数组,装着调用时传入的所有参数,它的原型是 Object.prototype,所以 Array.isArray(arguments) 是 false。要转成真数组,可以用 Array.from(arguments)、[...arguments],老代码里常见 Array.prototype.slice.call(arguments)。ES2015 之后,更推荐直接用剩余参数 function fn(...args),这里的 args 本身就是真数组。

  • 类数组有 length 和下标,但没有数组方法
  • arguments 的原型是 Object.prototype
  • 转换用 Array.from、展开或 slice.call
  • 箭头函数没有自己的 arguments,用剩余参数代替

在函数里看看 arguments 是什么

在函数里把 arguments 的几个特征打印出来,就能看清它和数组的区别。

能读下标,但没有数组方法JavaScript
function demo() {
  console.log(arguments.length, arguments[0])
  console.log(Array.isArray(arguments), typeof arguments.map) // 不是数组,没有 map
  console.log(Object.prototype.toString.call(arguments))

  const list = Array.from(arguments) // 转成真数组
  console.log(Array.isArray(list), list.map((s) => s.toUpperCase()).join(','))
}
demo('a', 'b')
查看输出与解释
2 a
false undefined
[object Arguments]
true A,B

arguments 像一张打印出来的名单,能按序号查人,但没有表格软件那些排序、筛选功能。转成数组后,这些功能就都有了。 三种转换写法的区别在于对输入的要求。[...arguments] 依赖迭代器,arguments 在现代引擎里是可迭代的,没问题;但对于自己拼出来的 { 0: 'a', length: 1 },展开会报错。Array.from 两种都支持。Array.prototype.slice.call(obj) 只看 length 和下标,是 ES5 时代的通用写法。

非严格模式下的形参联动

arguments 还有一个数组没有的行为:在非严格模式下,如果函数只用了简单形参,arguments[0] 和第一个形参是绑在一起的,改一个另一个也跟着变。

严格模式和非严格模式对比JavaScript
function sloppy(a) {
  arguments[0] = 'changed' // 非严格模式:a 也被改了
  return a
}

function strict(a) {
  'use strict'
  arguments[0] = 'changed' // 严格模式:a 不受影响
  return a
}

console.log(sloppy('orig'), strict('orig'))
查看输出与解释
changed orig

这种联动很容易造成难以理解的 bug,所以严格模式取消了它。另外只要函数用了默认参数、剩余参数或者解构参数,即使在非严格模式下,联动也会被关闭。ES 模块和 class 内部默认就是严格模式。

剩余参数才是新代码的写法
function sum(...nums) { return nums.reduce((a, b) => a + b, 0) } 里的 nums 是真数组,直接能用 reduce,不需要任何转换。它还能和普通形参一起用,比如 function log(level, ...messages),只收集剩下的参数,而 arguments 永远包含全部参数。
回答前,多想一步

容易答错的地方

在箭头函数里用 arguments
箭头函数没有自己的 arguments,在里面访问到的是外层普通函数的 arguments;如果外层没有函数,就会报 ReferenceError,在 Node.js 的 CommonJS 模块里则会拿到模块包装函数的参数。箭头函数需要所有参数时,用 (...args) => {}。
以为 arguments.length 是形参个数
arguments.length 是这次调用实际传了几个参数。function f(a, b) {} 调用 f(1) 时,arguments.length 是 1。声明的形参个数要用 f.length 读,它是 2。f.length 只数第一个默认参数或剩余参数之前的形参。
以为所有类数组都能直接展开
arguments、NodeList、字符串都实现了迭代器,可以展开;但普通的 { length: 2, 0: 'a', 1: 'b' } 没有迭代器,[...obj] 会抛 TypeError。不确定时用 Array.from。
试着用自己的话回答

面试官还会怎么问?

除了 arguments,还有哪些常见的类数组?

DOM 查询结果 NodeList 和 HTMLCollection、字符串、TypedArray,以及 jQuery 对象。HTMLCollection 是实时的,比如 document.getElementsByTagName('div') 返回的集合,页面新增一个 div,它的 length 立刻就变了,边遍历边删除时要特别小心。

不转换,能直接对 arguments 调用数组方法吗?

可以借用。Array.prototype.map.call(arguments, fn)、Array.prototype.join.call(arguments, ',') 都能用,因为大多数数组方法只依赖 length 和下标,不要求 this 是真数组。

arguments.callee 还能用吗?

严格模式下访问会抛 TypeError。它以前用来在匿名函数里递归调用自己,现在应该给函数表达式起个名字,比如 const f = function fact(n) { return n <= 1 ? 1 : n * fact(n - 1) }。

从一道题,走向一组知识

把知识连起来

数组与集合

找数组元素的下标,什么时候用 findIndex,什么时候用 indexOf?

arguments 没有 indexOf 和 findIndex,要在参数里查找时得先转成数组或用 call 借用。

数组与集合

稀疏数组的空位和 undefined 有什么区别,为什么 Array(n).map 不执行?

用 Array.from 转换类数组时,缺失的下标会变成真实的 undefined,和空位的区别在那题讲清楚了。

放回知识体系中复习JavaScript 进阶知识

参考资料

  • The arguments object

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 在函数里看看 arguments 是什么
  3. 非严格模式下的形参联动
  4. 容易答错的地方
  5. 面试官还会怎么问
  6. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑