作为参数定义的函数的闭包机制相关技术问询
关于闭包:为什么作为参数传入的函数也能访问外层变量?
哈哈,这个问题问得太戳点了!我刚啃闭包概念的时候也卡过这个弯儿,咱们掰开揉碎了说~
首先得把闭包的核心本质拎出来:函数的作用域链是在「定义的时候」就确定的,跟它后来被传到哪里、在哪里调用完全没关系。这是解开你疑惑的关键!
举个你可能正在纠结的代码例子:
function outer() { const a = 10; // 你理解的普通闭包函数 function foo() { console.log(a); // 能访问a,没问题 } foo(); // 你疑惑的:作为参数传入的函数 bar(function() { console.log(a); // 为啥这里也能访问a? }); } function bar(func) { func(); // 在bar的作用域里调用这个函数 } outer();
咱们来拆解这个匿名参数函数:
- 它是在
outer函数的内部定义的,定义的那一刻,它就捕获了outer的词法环境(包含变量a的作用域),把这个环境打包进了自己的作用域链里。 - 后来它被当作参数传给
bar,在bar的作用域里被调用,但这时候它的作用域链还是定义时的那一套——依然能找到outer里的a。
你之前觉得“它从未成为包含变量a的作用域的闭包”,其实刚好相反:它完完全全是闭包!闭包的定义就是「函数能够访问并保留自己定义时的词法作用域,哪怕在这个作用域之外执行」,这个匿名函数完美符合:在outer的作用域里定义,在bar的作用域(外层作用域之外)执行,却依然能拿到a,这就是闭包在起作用。
再给你补个反例加深理解:如果这个函数是在bar内部定义的,那它肯定访问不到a,因为它定义时的词法环境是bar的作用域,根本没有a这个变量:
function outer() { const a = 10; bar(); } function bar() { function func() { console.log(a); // ReferenceError: a is not defined } func(); } outer();
说白了,闭包看的是「函数在哪里出生」,不是「函数在哪里干活」——只要是在包含a的作用域里定义的函数,不管它是被直接调用、被赋值给变量、还是被当作参数传走,它都能牢牢抓住a所在的作用域,这就是闭包的魔力~
内容的提问来源于stack exchange,提问作者Return-1
相关产品推荐
相关产品推荐

