arguments 对象

arguments 是一个类数组对象,包含函数调用时传入的所有参数,仅在普通函数中可用,箭头函数没有 arguments 对象。

#resource / javascript #resource / ecmascript #type / concept #status / growing

[!info] related notes

arguments 对象

一句话定义

arguments 是一个类数组对象,包含函数调用时传入的所有参数,仅在普通函数中可用,箭头函数没有 arguments 对象。

核心机制

基本行为

function fn(a, b, c) {
  console.log(arguments.length); // 3
  console.log(arguments[0]);     // 1
  console.log(arguments[1]);     // 2
  console.log(arguments[2]);     // 3
}

fn(1, 2, 3);

关键特性

  1. 类数组对象:有 length 属性,可以通过索引访问,但不是真正的数组
  2. 仅普通函数可用:箭头函数没有 arguments
  3. 包含所有参数:包括超出形参数量的参数
  4. 与形参同步:在非严格模式下,arguments 和形参是同步的

arguments 与命名参数的绑定关系

arguments 可以理解为函数执行时创建的一个”静态数组快照”,但它和命名参数之间存在双向同步(非严格模式下)。

已传递的参数:双向同步

function log(a, b, c, d) {
  console.log(a, b, c, d); // 1, 2, 3, undefined

  arguments[0] = 'bfe';
  console.log(a, b, c, d); // "bfe", 2, 3, undefined

  a = 'changed';
  console.log(arguments[0]); // "changed"
}

log(1, 2, 3);

arguments[0]a 指向同一个绑定,改一个另一个跟着变。

未传递的参数:不同步

function log(a, b, c, d) {
  arguments[3] = 'dev';
  console.log(d);          // undefined(没变)
  console.log(arguments[3]); // "dev"(只改了 arguments 自身)
}

log(1, 2, 3);

调用时只传了 3 个参数,arguments 内部只有 3 个元素。给 arguments[3] 赋值只是在 arguments 对象上新增了一个属性,不会同步到 d,因为 d 在 arguments 中没有对应的槽位。

总结规律

操作效果
修改 arguments[n],n < 实际传参个数同步修改对应的命名参数
修改 arguments[n],n >= 实际传参个数只在 arguments 对象上操作,不影响命名参数
修改命名参数,n < 实际传参个数同步修改对应的 arguments[n]
修改命名参数,n >= 实际传参个数不影响 arguments

详细示例

1. 基本使用

function sum() {
  let total = 0;
  for (let i = 0; i < arguments.length; i++) {
    total += arguments[i];
  }
  return total;
}

sum(1, 2, 3);      // 6
sum(1, 2, 3, 4, 5); // 15

2. 转换为真正的数组

function fn() {
  // 方法 1:Array.from()
  const arr1 = Array.from(arguments);
  
  // 方法 2:展开运算符
  const arr2 = [...arguments];
  
  // 方法 3:slice
  const arr3 = Array.prototype.slice.call(arguments);
  
  // 方法 4:apply
  const arr4 = [].slice.apply(arguments);
}

3. 严格模式下的行为

'use strict';

function fn(a, b) {
  a = 10;
  console.log(arguments[0]); // 1(不同步)
  console.log(a);            // 10
}

fn(1, 2);

与 rest 参数的区别

特性argumentsrest 参数
类型类数组对象真正的数组
可用性仅普通函数所有函数(包括箭头函数)
包含内容所有参数只包含剩余参数
数组方法需要转换直接可用
严格模式不与形参同步不受影响
// arguments:类数组对象
function sumArgs() {
  // console.log(arguments.reduce); // undefined
  return Array.from(arguments).reduce((a, b) => a + b, 0);
}

// rest 参数:真正的数组
function sumRest(...args) {
  // console.log(args.reduce); // function
  return args.reduce((a, b) => a + b, 0);
}

// 箭头函数只能用 rest 参数
const sumArrow = (...args) => args.reduce((a, b) => a + b, 0);

实际应用

1. 可变参数函数

function log(...args) {
  console.log('[LOG]', ...args);
}

log('User', 'logged', 'in'); 
// [LOG] User logged in

2. 参数转发

function wrapper() {
  // 将所有参数转发给另一个函数
  return actualFunction.apply(this, arguments);
}

3. 函数重载模拟

function add() {
  if (arguments.length === 2) {
    return arguments[0] + arguments[1];
  } else if (arguments.length === 3) {
    return arguments[0] + arguments[1] + arguments[2];
  }
  throw new Error('Invalid number of arguments');
}

add(1, 2);      // 3
add(1, 2, 3);   // 6

常见误解

1. 箭头函数没有 arguments

const arrowFn = () => {
  // console.log(arguments); // ReferenceError: arguments is not defined
};

// 箭头函数可以使用外层函数的 arguments
function outer() {
  const inner = () => {
    console.log(arguments[0]); // 可以访问 outer 的 arguments
  };
  inner();
}
outer(1); // 1

2. arguments 不是数组

function fn() {
  console.log(Array.isArray(arguments)); // false
  
  // 需要转换才能使用数组方法
  const arr = Array.from(arguments);
  console.log(Array.isArray(arr)); // true
}

3. 严格模式下的同步问题

'use strict';

function fn(a) {
  a = 100;
  console.log(arguments[0]); // 1(不同步)
}

fn(1);

现代替代方案

推荐使用 rest 参数

// ❌ 旧方式:使用 arguments
function sum() {
  return Array.from(arguments).reduce((a, b) => a + b, 0);
}

// ✅ 新方式:使用 rest 参数
function sum(...args) {
  return args.reduce((a, b) => a + b, 0);
}

何时仍需使用 arguments

  1. 兼容旧代码:旧浏览器可能不支持 rest 参数
  2. 需要访问调用者信息arguments.callee(严格模式不可用)
  3. 与现有 API 交互:某些旧 API 可能依赖 arguments

BFE.dev 相关题目

  • 19. this:理解函数调用时的参数传递
  • 33. this II:理解 arguments 和 this 的关系

面试要点

  1. 类数组对象:知道 arguments 不是真正的数组
  2. 箭头函数限制:箭头函数没有 arguments
  3. 严格模式:严格模式下 arguments 不与形参同步
  4. 现代替代:推荐使用 rest 参数替代 arguments
  5. 转换方法:知道如何将 arguments 转换为数组

信息参考

创建于 2026/3/31 更新于 2026/5/27