首页 > 解决方案 > 如何立即调用 IIFE 以防止它污染全局范围?

问题描述

在关于立即调用函数表达式(关于提供的代码片段)的 Udacity 课程中,它说:

返回的函数关闭(即捕获)hi 变量。这允许 myFunction 维护一个私有的、可变的状态,在函数之外无法访问!更重要的是: 因为表达的函数被立即调用,IIFE 很好地包装了代码,这样我们就不会污染全局范围

我正在努力理解立即调用匿名函数与防止变量hi“污染全局范围”有什么关系,并且由于hi已经在函数中定义,它不是已经在本地/私有范围内了吗?

const myFunction = (
  function () {
    const hi = 'Hi!';
    return function () {
      console.log(hi);
    }
  }
)();

标签: javascriptscopeiiferevealing-module-pattern

解决方案


在现代 JavaScript 中,你有let和块作用域(我很确定const也有块作用域),所以你可以这样做:

let myFunction;
{
    let hi = 'Hi!';
    myFunction = function () {
        console.log(hi);
    };
}

myFunction不会泄漏hi到周围的范围内。

在传统的 JavaScript 中,你只有一个var函数作用域,你可以这样做:

var myFunction;
function a_private_scope() {
    var hi = 'Hi!';
    myFunction = function () {
        console.log(hi);
    };
}
a_private_scope();

a_private_scope限制了 的范围hi,但是(它是一个函数声明)它需要显式调用,并且我们仍然将名称泄漏到周围的范围(这次是a_private_scope,作为函数服务的范围的名称)。

通过使用函数表达式并立即调用它,我们避免了第二种名称污染:

var myFunction;
(function () {
    var hi = 'Hi!';
    myFunction = function () {
        console.log(hi);
    };
})();

现在,在外部范围中定义的唯一内容是myFunction. 用作作用域的匿名函数hi没有可能污染周围作用域的名称。

最后我们可以通过使用返回值来清理一下,所以我们不必提及myFunction两次:

var myFunction = function () {
    var hi = 'Hi!';
    return function () {
        console.log(hi);
    };
}();

(这也为我们节省了一对,( )因为function关键字不再出现在语句的开头。)


推荐阅读