【js篇】为什么 arguments是类数组?如何遍历类数组?

50 阅读3分钟

在 JavaScript 中,arguments 是一个非常特殊的对象,它存在于每一个非箭头函数中,用于访问函数调用时传入的所有参数。虽然它看起来像数组,但并不是真正的数组。


✅ 一句话总结

arguments类数组对象,因为它具有 length 属性和以数字为键的索引属性,但没有继承 Array.prototype,因此不能直接使用数组方法。可以通过 callArray.from()扩展运算符将其转换为数组后遍历。


✅ 一、为什么 arguments 是类数组而不是数组?

🔹 1. 结构上像数组

function example(a, b) {
  console.log(arguments);
  // 输出:{ '0': a, '1': b, length: 2, callee: function }
}
example('hello', 'world');
  • 有数字索引(0, 1, ...)
  • length 属性
  • 可以通过 arguments[0] 访问第一个参数

🔹 2. 本质上是对象

  • arguments 是一个类数组对象(Array-like Object),不是 Array 的实例;
  • 没有继承 Array.prototype,因此不能使用 forEachmapfilter 等数组方法;
  • 它包含一些特殊属性:
    • length:传入参数的个数;
    • callee:指向当前函数本身(在严格模式下不可用);

🔹 3. 历史与性能原因

  • 在早期 JavaScript 设计中,为了性能和轻量级arguments 被设计为对象而非数组;
  • 创建真正的数组会带来额外的开销(如方法绑定);
  • 类数组结构足以满足参数访问的需求;

✅ 二、如何遍历类数组对象?

虽然 arguments 不能直接使用数组方法,但我们可以通过以下几种方式“遍历”它。


🔹 方法 1:借用数组方法(call / apply

function example() {
  // 使用 call 借用数组的 forEach
  Array.prototype.forEach.call(arguments, function (arg) {
    console.log(arg);
  });
}

example('a', 'b', 'c');
// 输出:a, b, c
  • ✅ 兼容性好,适用于老版本浏览器;
  • ✅ 不创建新数组,节省内存;

🔹 方法 2:使用 Array.from() 转换为数组

function example() {
  const args = Array.from(arguments);
  args.forEach(function (arg) {
    console.log(arg);
  });
}

example('x', 'y', 'z');
  • ✅ 语法简洁,语义清晰;
  • ✅ 支持映射函数:Array.from(arguments, x => x * 2)
  • ✅ ES6 标准方法,推荐现代项目使用;

🔹 方法 3:使用扩展运算符(Spread Operator)

function example() {
  const args = [...arguments];
  args.forEach((arg) => {
    console.log(arg);
  });
}

example(1, 2, 3);
  • ✅ 代码最简洁;
  • ✅ 可与其他数组操作链式调用;
  • ✅ 需要环境支持 ES6+;

✅ 三、其他遍历方式(传统 for 循环)

虽然不是“数组方法”,但最原始的 for 循环也可以直接遍历类数组:

function example() {
  for (let i = 0; i < arguments.length; i++) {
    console.log(arguments[i]);
  }
}
  • ✅ 性能最好;
  • ✅ 无需转换;
  • ✅ 适用于对性能要求极高的场景;

✅ 四、现代替代方案:使用 ...rest 参数

在 ES6 中,推荐使用 rest 参数替代 arguments

function example(...args) {
  // args 是真正的数组!
  args.forEach(arg => console.log(arg));
}

example('hello', 'world');
  • args 是真正的数组,可直接使用所有数组方法;
  • ✅ 语法更清晰;
  • ✅ 支持解构和默认值;
  • ✅ 推荐在新项目中使用;

✅ 五、一句话总结

arguments 是类数组对象,因为它具备索引和 length,但缺少数组方法。可通过 callArray.from、扩展运算符或 for 循环遍历。在现代 JavaScript 中,建议使用 ...rest 参数替代 arguments,获得真正的数组体验。


💡 进阶建议

  • 在箭头函数中,arguments 不可用,必须使用 ...rest
  • Array.from() 和扩展运算符不会影响原始 arguments
  • 使用 Array.isArray(arguments) 返回 false,可验证其非数组身份;
  • 注意 arguments.callee 在严格模式下已被弃用;