【问题标题】:How does an IIFE's being called immediately prevent it from polluting global scope?如何立即调用 IIFE 以防止它污染全局范围?
【发布时间】:2018-11-29 03:31:54
【问题描述】:

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

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

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

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

【问题讨论】:

  • 关键是要避免让hi 可以从全局范围访问,并创建另一个不能与之冲突的名称。
  • 如果你不立即调用它,你必须给它一个名字,污染外部范围。
  • 基本上是myFunction = function () { console.log(hi) },因为它是 iife 的结果,但如果您不使用 iife,则必须在外部范围内声明 hi。如果您在最高范围内执行此操作,最终会导致 hi 在您的 window 对象或 global 对象中(取决于您所拥有的),从而污染它。
  • 只要变量在块(let 或 const 的情况下)或函数(car 的情况下)内,就不会污染全局范围

标签: javascript scope iife revealing-module-pattern


【解决方案1】:

在现代 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 关键字不再出现在语句的开头。)

【讨论】:

    【解决方案2】:

    如何立即调用 IIFE 以防止它污染全局范围?

    它没有。

    作为一个函数可以阻止它污染全局范围。

    在函数内声明的变量只存在于该函数内

    【讨论】:

    • 他们为什么需要生活?我们可以只使用普通功能吗?为什么说 iife 可以防止全球范围污染?
    • 您不需要 IIFE。您可以使用普通函数(但您必须 sometime 调用它,为什么不立即调用它呢?)。再看答案的最后两句。
    • 大家都知道!重点不是那个!关键是提到 IIFE 的优点之一是它们不会污染全局范围!你们怎么看不出区别!当它发生在正常功能中时,为什么他们会这样做!
    • 唯一的区别是不是写“function funcName() {whatever; } funcName();”你写“(函数(){随便;})();”这避免了 funcName 到处乱扔。这是一件小事,但在一个包含大量一次性函数的大型项目中,它可能会保护您免受意外的函数名称重用。
    猜你喜欢
    • 2021-01-12
    • 2014-04-09
    • 1970-01-01
    • 1970-01-01
    • 2018-12-16
    • 2021-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多