arguments是执行上下文变量环境中由引擎动态创建的类数组对象,非手动构造,仅存于非箭头函数,具双向映射(非严格模式)、只读快照(严格模式)及callee等历史特性;rest参数则是es6语法级真数组,语义明确、行为确定、可优化且兼容箭头函数。

arguments 是函数执行上下文(Execution Context)中自动创建的特殊对象,它的存在和行为由 JavaScript 引擎在函数调用时动态生成与管理,不是开发者手动构造的。它本质上是执行上下文「变量环境」的一部分,与形参绑定、内存布局、严格模式策略密切相关。
arguments 与执行上下文的初始化关系
当函数被调用时,引擎会为它创建一个新的函数执行上下文。该上下文初始化阶段包含几个关键步骤:
- 建立词法环境(Lexical Environment)和变量环境(Variable Environment)
- 根据函数定义的形参列表,在变量环境中声明对应变量(如 a、b),初始值为 undefined 或传入实参
- 将所有实际传入的参数(无论是否匹配形参个数)收集并封装成 arguments 对象,存入当前上下文的变量环境中
- 若函数是非箭头函数,arguments 作为隐式绑定属性被注入;箭头函数则无此属性,会沿作用域链向上查找(可能找不到)
arguments 的类数组结构与内存实现
它并非 Array 实例,而是一个拥有 length 属性和数字索引(0、1…)的普通对象。V8 等现代引擎对其做了特殊优化:
- 底层通常采用“参数映射表 + 值存储区”双层结构:索引直接指向栈或寄存器中的实参位置(非拷贝),提升访问效率
- 在非严格模式下,引擎维持形参与 arguments[i] 的双向映射——修改任一端都会触发另一端同步更新(本质是共享同一内存地址)
- 严格模式下,该映射被切断,arguments 变成只读快照,形参与它各自独立,避免副作用
arguments.callee 与执行栈的隐式关联
callee 是 arguments 的一个属性,指向当前正在执行的函数本身。它在匿名递归或调试追踪中曾被使用,但已被严格模式禁用,且在 ES5+ 中不推荐使用:
- 它的存在依赖于执行上下文的「正在运行函数引用」,即当前上下文的 active function object
- 引擎需在调用栈帧(call frame)中保留对该函数的强引用,才能支持 callee 安全返回
- 现代引擎(如 V8 TurboFan)在优化内联或尾调用时,可能直接移除 callee 支持以提升性能
为什么 rest 参数(...args)逐渐替代 arguments
ES6 引入的 rest 参数是语法层面的替代方案,它从设计上规避了 arguments 的诸多底层约束:
- rest 是真数组,可直接使用 map、filter、展开运算符等,无需转换
- 它不参与形参映射,不受严格/非严格模式影响,行为确定且可预测
- 引擎能对 rest 参数做更激进的优化(如栈内连续分配、避免对象创建开销)
- 它明确限定了“剩余参数”的语义边界,而 arguments 总是包含全部实参(含已命名的),容易造成混淆











