在You Don't Know Javascript系列中,IIFE的1/3被描述为不是闭包本身,但只有当它们在词法范围之外被执行时才会被执行:
第3章介绍了IIFE模式。虽然经常这样说 IIFE(单独)是观察到闭合的一个例子,我会有点 不同意,根据我们上面的定义。
这段代码“有效”,但并不是严格意义上的封闭。 为什么?因为函数(我们在这里命名为“IIFE”)不会被执行 在其词汇范围之外。它仍然在那里被调用 声明的范围(也包含的封闭/全局范围) 一个)。 a通过正常的词法范围查找,而不是真正的通过 闭合。
var a = 2;
(function IIFE(){ // not actually a "closure"
console.log( a );
})();
在这个SO post中,给出了以下片段作为闭包的示例:
for (var i = 0; i < someVar.length; i++)
(function (i) {
window.setTimeout(function () {
alert("Value of i was "+i+" when this timer was set" )
}, 10000);
})(i);
我试图从闭包的定义(在this medium article中定义)中理解这一点:
要使用闭包,只需在另一个函数内定义一个函数即可 暴露它。要公开函数,请将其返回或传递给另一个函数 功能。 ......
内部函数可以访问外部的变量 函数范围,即使在返回外部函数之后。
我知道闭包是一个“有状态函数”,它是
一种“记住”并继续访问函数范围的方法(它的 变量)甚至一旦函数完成运行。
所以在这个例子中,我看到循环的i
在传递到结束IIFE时会被记住。
我的问题是:
“传递到另一个功能或返回”部分在哪里发生?我的猜测是,IIFE能够在每次迭代时记住外部i
for循环值,因为IIFE被传递到窗口?
基本上,我的理解是,在Garbage收集器清除外部作用域之后,将定义作为记住外部作用域的值,并且它的用法是通过返回它并在其词法范围之外访问它来公开闭包。它是否正确?那么“在词汇范围之外访问它”会发生在哪里?
答案 0 :(得分:3)
在这个示例中,我看到循环#{1}}在传递到结束IIFE时会被记住
没有。 IIFE仅提供要记住的i
值的范围。作为引用状态的引号,IIFE函数不是闭包。 使用 i
的函数表达式是闭包:
i
&#34;传递到另一个函数或返回&#34;部分发生了吗?
传递到(function IIFE(i) {
// this is the scope of i
window.setTimeout(function closure() {
// this function closes over i
alert("Value of my local 'i' is still "+i+" even after 10 seconds");
}, 10000);
})(0);
// ^ this is some arbitrary value passed to the IIFE - it could have been a loop variable
的{{1}}函数会从closure
通常不再定义的地方调用它 - 如果它不是&#39 ;关闭。