闭包技术疑问:内部函数直接访问外部函数参数的实现原理
为什么这两个闭包实现效果相同?
嘿,这个问题问得特别到位!其实这两个示例本质上是同一个逻辑的不同写法,核心都绕不开JavaScript闭包的工作机制——咱们一点点拆解清楚:
首先得明确:函数的参数本身就是其作用域内的局部变量,和你用let/var声明的变量没有本质区别。
先看示例1的逻辑
function firstex1(x) { let foo = x; // 把外部参数x赋值给作用域内的变量foo console.log(foo) function second() { return foo + 100 } return second } console.log("Example 1: "+ firstex1(1)()); // 输出101
这里second作为内部函数,形成了闭包:它捕获了外部函数firstex1的作用域,所以哪怕firstex1执行完毕并退出,second依然能访问到该作用域里的foo变量。
再看示例2的逻辑
function firstex2(x) { console.log(x) function second() { return x + 100 } return second } console.log("Example 2: "+ firstex2(1)()); // 同样输出101
这里的x并不是什么“特殊的外部值”,它就是firstex2作用域里的局部变量(和示例1里的foo地位完全一样)!当firstex2执行时,传入的1被赋值给参数x,这个x就存在于firstex2的作用域中。
当second被返回时,它同样形成了闭包,捕获的是firstex2的整个作用域——自然就包含了这个x变量。所以哪怕firstex2执行结束,second依然能访问到当初传入的x的值,和示例1里访问foo的逻辑完全一致。
换个写法帮你理解
你可以把示例2的参数x看作是手动声明的局部变量,它和示例1的foo完全等价:
// firstex2的等价写法 function firstex2() { let x = arguments[0]; // 参数本质就是函数作用域内的局部变量 console.log(x); function second() { return x + 100; } return second; }
总结一下
闭包的核心是内部函数保留对外部函数作用域的访问权,不管你是直接访问外部函数的参数,还是把参数赋值给另一个变量后再访问,只要这个标识符属于外部函数的作用域,闭包就会帮你“留住”它。所以这两个示例的运行效果完全相同。
内容的提问来源于stack exchange,提问作者John Nada
相关产品推荐
相关产品推荐

