前端进阶之旅前端进阶之旅
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库arguments 与形参(parameters)的区别
JSJavaScript函数与作用域

JavaScript 中 arguments 对象与函数参数(parameters)有何区别?

arguments 保存每次调用传入的实参,是类数组对象;parameters 是声明函数时给出的具名形参。两者可能同步,也可能完全独立,取决于严格模式与参数写法。

前端进阶之旅 · 一题精讲更新于 2026.09.05
JavaScript#函数与作用域
先看核心答案读代码示例
理解线索

实参集合与形参绑定

  1. 来源与职责arguments 记录本次调用的实参,parameters 是声明时的形参名。
  2. 数量与可访问性实参数量看 arguments.length;函数 length 有默认值和 rest 边界
  3. 原型与方法类数组而非数组,有 length 和索引,没有 Array 的方法。

同步只发生在非严格且参数全为简单名字时;否则永远不要假设两者一致。

核心回答

先记住这个答案

函数调用时会基于实际传入的参数创建 arguments 对象;parameters 是函数定义中声明的形参,例如 function f(a, b) 中的 a、b,是函数内的局部绑定。arguments 具有数字索引和 length,但没有数组方法。在非严格且参数只由简单名字组成的函数里,修改 arguments[0] 会同步改变对应形参,反之亦然;严格模式或存在默认参数、剩余参数、解构时,这种同步消失。

  • arguments 保存实际传入值,是类数组对象
  • parameters 是声明的形参,函数体内是局部绑定
  • 严格模式或默认参数下二者不再同步

形参绑定与 arguments 的生成规则

形参是函数定义中的局部绑定,例如 function search(id) 中的 id。普通函数通常提供一个记录本次实参的 arguments 对象。调用 search(1, 2, 3) 时,其 arguments.length 为 3,而 search.length 为 1。函数的 length 统计第一个带默认值的形参之前的参数个数,不计剩余参数;一个解构参数按一个计数,不能把它一概叫作全部形参数量。

arguments 被叫作 array-like object:它有 length 属性和索引,也实现了 Symbol.iterator,但它不继承数组方法。arguments.map 并不存在,想遍历可以先 Array.from(arguments) 转成数组。typeof arguments 的结果是 "object",用 Array.isArray(arguments) 会得到 false。

非严格模式且参数列表只有简单名字时,实际传入的实参项可与对应形参双向关联。严格模式、默认参数、剩余参数或解构参数会关闭这种映射。即使满足映射条件,也不能假设没有传入的参数项会凭空建立关联;删除关联的索引属性等操作还会解除对应映射。工程代码应显式使用参数,不依赖这种历史行为。

相同赋值在不同参数模式下的结果JavaScript
function loose(value) { arguments[0] = 7; return value; }
function strict(value) { 'use strict'; arguments[0] = 7; return value; }
function defaults(value = 1) { arguments[0] = 7; return value; }
console.log(loose(2));
console.log(strict(2));
console.log(defaults(2));
console.log(loose());
function counts(a, b = 0, ...rest) { return arguments.length; }
console.log(counts.length, counts(1, 2, 3));
查看输出与解释
7
2
2
undefined
1 3

按普通脚本运行,第一项保留非严格模式。简单参数的已传入实参项可以同步;严格模式和默认参数不映射。未传入参数时,补写 arguments[0] 不会补建映射。最后一行对比函数声明的 length 与本次实参数量。

可变参数数量但只声明一个形参的场景

场景:函数 prefixJoin(prefix) 只声明一个形参,调用方却会传多个字符串:prefixJoin(">", "A", "B", "C")。由于 arguments 记录全部实参,函数体内先 Array.prototype.slice.call(arguments, 1) 把第二个及之后的实参复制成数组,再使用 join(prefix),最终返回 "A>B>C"。这里声明形参数量是 1,实际实参数量是 4,二者不一致正是 arguments 发挥作用的地方。

这个方案必须写在普通函数里,因为箭头函数没有自己的 arguments(若改用箭头函数,需要换成剩余参数写法);也不能事先列出所有形参,因为调用方数量不定。选择先进行数组转换,是因为 arguments 本身没有 join 或 map,直接当数组使用会得到 TypeError。转换后所有后续处理都基于普通数组,也不再受到 arguments 与形参同步语义的影响。

什么条件下不能依赖 arguments 与形参同步

最容易失效的写法是在函数体内用 arguments[0] = 999 去修改第一个形参。在无默认参数的旧式非严格函数中它确实有效;但函数中写了严格模式指令,或声明形参时带 a = 1 默认值,修改就不会同步到形参。反过来,给形参重新赋值后读取 arguments[0] 仍会得到调用时传入的旧值,因此不能盲目依赖二者互相更新。

箭头函数没有自己的 arguments 绑定,引用这个名字时会查找外层作用域;外层也没有相应绑定时会报错。箭头函数需要当前调用的全部实参时,应写剩余参数,例如 (...values) => values.length。剩余参数直接得到数组,可变参数 API 通常优先采用这种更明确的表达。

回答前,多想一步

容易答错的地方

把 arguments 当作真正的数组
它确实有 length 和下标,但原型链上并没有 Array.prototype,因此 arguments.forEach 是 undefined,不能直接调用。可以用 Array.from(arguments)、[...arguments] 或 Array.prototype.slice.call(arguments) 转成真数组。
认为严格模式下不能使用 arguments
严格模式仍然允许使用 arguments,只是 arguments 与形参不再双向同步,同时不能访问 arguments.callee。若函数的形参里包含默认值、剩余参数或解构参数,函数体内也不能再写 "use strict"; 指令,这是语法限制,会抛出语法错误。
试着用自己的话回答

面试官还会怎么问?

如何把 arguments 转换为真正的数组?

可以使用 Array.from(arguments)、[...arguments] 或 Array.prototype.slice.call(arguments)。后者在老环境兼容性更好。转换结果都是普通数组,之后可以安全调用数组方法,也不会再受 arguments 与形参之间的同步关系影响。

默认参数会出现在 arguments 中吗?

默认参数不会填入 arguments。比如 function f(a = 1){} 调用 f() 时,arguments.length 是 0,arguments[0] 是 undefined;调用 f(5) 时 arguments[0] 才是 5。同时在这种函数中,arguments 与 a 的更新不联动。

arguments.callee 被禁后如何获得当前函数自身?

应使用具名函数表达式或在作用域内持有函数名引用,例如 const f = function myself(){ console.log(myself); };。严格模式禁止访问 arguments.callee,因为通过它引用当前执行函数会让内联等优化难以进行,而且具名函数表达式已经能覆盖函数自引用(如递归)的需求。

从一道题,走向一组知识

把知识连起来

手写与交互性能

防抖和节流有什么区别?

防抖封装需要保存本次调用的参数,不能把外层 arguments 与稍后回调的参数混淆。

作用域与函数

JavaScript 闭包是什么?

箭头函数查找外层 arguments 涉及词法绑定,闭包页解释这种绑定如何保留。

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

参考资料

  • The arguments object

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

本题目录
  1. 先记住这个答案
  2. 形参绑定与 arguments 的生成规则
  3. 可变参数数量但只声明一个形参的场景
  4. 什么条件下不能依赖 arguments 与形参同步
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

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

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