函数参数在编译阶段被绑定到变量环境,实参值立即覆盖形参初始值;同名let/const声明报语法错误;arguments在非严格模式下与参数双向同步。

函数执行时,参数不是简单“塞进去”就完事的。它发生在执行上下文创建阶段的关键环节,直接影响变量初始化顺序和作用域行为。
参数在编译阶段就被绑定到变量环境
当函数被调用,V8 首先进入编译阶段(Creation Phase),此时会做三件事:扫描形参、提升 var 和 function 声明、统一形参与实参值。其中,形参名会被提前加入变量环境(Variable Environment),初始值为 undefined;紧接着,实参值会立即覆盖对应形参的值——这个过程发生在任何代码执行之前。
- 哪怕函数体第一行是
console.log(a),a也已持有实参值,不会输出undefined - 如果实参未传,形参保持
undefined,而非报错 - 这个绑定只发生在变量环境中,
let/const声明的同名变量会触发重复声明错误(因进入暂时性死区前已存在绑定)
参数与 var 声明同级,但优先于 var 初始化
形参和 var 变量共享变量环境,但参数赋值发生在 var 初始化之后、代码执行之前。也就是说:
-
var a = 10;在编译阶段只是声明a: undefined - 形参
a同样先被设为undefined,再被实参覆盖 - 若形参与
var同名,实参值最终生效;若无实参,则var的赋值语句会在执行阶段覆盖为10
参数不可被 let/const 重复声明
函数参数已在词法环境(Lexical Environment)中建立绑定,而 let/const 声明也写入同一词法环境。因此,在函数体内写 let a = 20 会导致 SyntaxError: Identifier 'a' has already been declared。
- 这是语法错误,不是运行时错误,发生在编译阶段
- 哪怕
let声明在参数使用之后,依然报错 - 想在函数内重新定义同名变量,只能用
var(会覆盖)或换名
arguments 对象与参数的关系
在非箭头函数中,arguments 是一个类数组对象,反映调用时传入的所有实参。它与形参是双向同步的(仅限非严格模式):
- 修改
arguments[0]会同时改变对应形参值 - 修改形参也会反映到
arguments对应索引 - 严格模式下,
arguments与参数解耦,修改互不影响 - 箭头函数没有
arguments,需用剩余参数...args替代
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











