IIFE作为闭包

时间:2017-07-17 18:39:17

标签: javascript scope closures iife

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收集器清除外部作用域之后,将定义作为记住外部作用域的值,并且它的用法是通过返回它并在其词法范围之外访问它来公开闭包。它是否正确?那么“在词汇范围之外访问它”会发生在哪里?

1 个答案:

答案 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 ;关闭。