为何使用剩余参数的函数与普通参数函数作用域表现不同?
问题:剩余参数函数内变量作用域差异疑问
代码示例
function test1(args){ let age = 23; // place debugger 1 here var name = 'prajval'; } test2(); function test2(...args){ let age = 23; // place debugger 2 here var name = 'prajval'; } test1();
调试器观测结果
调试器1(test1函数内)作用域
- Local(局部作用域)
- this: Window
- age: undefined
- args: undefined
- name: undefined
- Global(全局作用域)
调试器2(test2函数内)作用域
- Block(块级作用域)
- age: undefined
- name: undefined
- Local(局部作用域)
- this: Window
- args: []
- Global(全局作用域)
疑问
test2()中使用...args作为参数后,该函数内的其他变量声明被归入块级作用域。但我预期所有变量(args及内部变量声明)都应像test1()一样处于局部作用域中,为何会出现这种差异?
解答
这是JavaScript引擎处理剩余参数时的内部机制导致的调试器展示差异,并非变量访问规则出了问题。
核心原因
当函数使用剩余参数...args时,引擎会为函数体隐式创建一个隐形块级作用域:
- 剩余参数
args会被直接绑定到函数的局部作用域(也就是调试器里Local栏显示的args: []),这是因为剩余参数本质是函数参数的一部分,属于函数作用域层面的绑定。 - 函数体内的
let/const/var声明,会被放置在这个隐形块的作用域中,所以调试器会将它们归类到Block栏下。
而普通参数的函数(比如test1)不存在这个隐形块,所有变量声明直接挂载到函数的局部作用域,因此调试器统一显示在Local栏。
实际影响说明
这种分层只是调试器对引擎内部作用域结构的直观展示,完全不影响代码的正常运行:你在test2函数内依然可以自由访问age、name和args,变量的可访问性和普通参数函数没有任何区别——隐形块是函数作用域的子作用域,内部和外部的变量可以互相访问,不存在隔离问题。
内容的提问来源于stack exchange,提问作者Prajval Gahine
相关产品推荐
相关产品推荐

