javascript - IIFE 作为闭包

标签 javascript scope closures iife

You Don't Know Javascript系列中,IIFE 的 1/3 被描述为本身不是闭包,但前提是它们在词法范围之外执行:

Chapter 3 introduced the IIFE pattern. While it is often said that IIFE (alone) is an example of observed closure, I would somewhat disagree, by our definition above.

This code "works", but it's not strictly an observation of closure. Why? Because the function (which we named "IIFE" here) is not executed outside its lexical scope. It's still invoked right there in the same scope as it was declared (the enclosing/global scope that also holds a). a is found via normal lexical scope look-up, not really via closure.

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 中定义):

To use a closure, simply define a function inside another function and expose it. To expose a function, return it or pass it to another function. ...

The inner function will have access to the variables in the outer function scope, even after the outer function has returned.

我知道闭包是一个“有状态函数”,而且它是

a way to "remember" and continue to access a function's scope (its variables) even once the function has finished running.

因此,在这个示例中,我看到循环的 i 在传递到结束 IIFE 时会被记住。

我的问题是:

“传递给另一个函数或返回”部分发生在哪里?我的猜测是,IIFE 能够在每次迭代时记住外部 i for 循环值,因为 IIFE 被传递到窗口?

基本上,我的理解是,闭包定义为在垃圾收集器清理外部作用域后记住外部作用域的值,并且它的用法是通过返回闭包并在其词法范围之外访问它来公开闭包。它是否正确?那么“在词法范围之外访问它”发生在哪里?

最佳答案

in this example, I see that the loop's i is remembered when passed into the closing IIFE

没有。 IIFE 仅提供 i 的范围值得被记住的值(value)。正如您引用的引文所述, IIFE 函数不是一个闭包。 使用 i 的函数表达式是闭包:

(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

Where is the "passing to another function or returning" portion happening?

这是 closure函数被传递到 setTimeout ,这将从 i 的位置回调它通常将不再被定义 - 如果它不是一个闭包。

关于javascript - IIFE 作为闭包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45151381/

相关文章:

c# - 何时使用闭包的场景

python - 为什么python嵌套函数不称为闭包?

javascript - 在文本框javascript中设置光标位置

javascript - 在点击事件中,第一次点击时触发一次代码,其余代码在所有点击时运行

javascript - 在 ruby​​/rails 中创建交互式 ajax javascript 小部件

javascript - 定义的变量范围

javascript - js.dart scoped() undefined

ruby-on-rails - RailsAdmin 中的范围关联

oauth - 在 nodemailer 中通过 gmail oauth 发送电子邮件需要哪个范围?

javascript - 实现功能—— spy