【问题标题】:Javascript: difference between using an IIFE and a block statementJavascript:使用 IIFE 和块语句之间的区别
【发布时间】:2018-07-25 21:24:10
【问题描述】:

IIFE主要用于封装作用域

(function () {
    let myVar = 10; // not global
    // ...
}());

但为什么不直接使用块语句呢?

{
    let myVar = 10; // also not global
    // ...
}

除了作用域封装之外,使用 IIFE 还有其他好处吗?

【问题讨论】:

  • 变量 myVar 不是全局变量,因为关键字 let
  • 一旦 IIFE 完成,闭包中未返回的任何内容都将被丢弃,否则使用块语句,无论变量包含在什么范围内,都不一定会删除,myvar 可能会被删除留在一个更大的范围内,不希望或保证在其中可用。
  • 块范围是 ES6+ 的特性,它在 IE 等旧浏览器中不起作用。此外,只有 const 和 let 声明的变量是块作用域的。对于 var 你需要 IIFE
  • 块没有返回值。 IIFE 将来可能会被do expressions 取代。
  • 我意识到我可能会用太多的词混淆这个问题。道歉!不太罗嗦的版本是 IIFE 可以立即将某些内容返回到它被调用的范围内,而不会污染任何更高的范围或导致多次声明同一变量的语法错误。

标签: javascript syntax scope block iife


【解决方案1】:

块语句是相当新的功能。是的,在引入之前,通常使用 IIFE。

如今,我至少能想到一种情况,即 IIFE 不可替代。看看这个:

(async () => { const foo = await someAsyncFunction() })()

看到了吗? await 关键字只能存在于 async 函数中,因此如果您的包含 await 的表达式尚未被任何函数包装,则必须使用 async IIFE 包装它。

【讨论】:

  • 我认为异步的情况已经由顶级等待处理。在今天的 JS 中也是如此。
【解决方案2】:

IIFEs 利用函数作用域。用var 声明的函数和变量都在父函数的范围内。

Block statements 利用块作用域。用letconst 声明的变量在块内作用域。

块语句不封装用var 声明的函数或变量。

【讨论】:

    【解决方案3】:

    试试这个你会更好地理解这个概念:

    if(true){
     var something = 'something' // This is global now. Block scoping for var works fine inside function definition but not for **if statements** or similar ones
    }
    
    console.log(something)
    

    尝试将 var 更改为 let,您将无法访问 console.log 语句中的 something

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-24
      • 2020-05-18
      • 1970-01-01
      • 2012-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多