← [ BACK_TO_NOTES ]

arguments 对象

arguments 是一个类数组对象,包含函数调用时传入的所有参数,普通函数拥有自己的 arguments;箭头函数没有自身绑定,但可读取外层函数的 arguments。

#frontend #javascript #ecmascript #concept #growing

[!info] related notes

arguments 对象

一句话定义

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 不是静态数组快照。下面的双向同步仅适用于非严格模式的简单参数列表(无默认值、解构或 rest),并且只映射已传入的对应形参;模块天然处于严格模式。删除索引等操作还可解除映射。

已传递的参数:双向同步

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
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/10/7
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本