代码之家  ›  专栏  ›  技术社区  ›  dayna j

JavaScript iifes(立即调用的函数表达式)是否仍然相关?[副本]

  •  3
  • dayna j  · 技术社区  · 6 年前

    我对这个概念的理解是,iifes允许您模拟一个“私有”作用域,从而防止全局作用域变得混乱。

    既然ECMAScript 6已经看到了相当广泛的实现,并且允许我们通过const和let访问块级别的作用域,那么还有其他理由使用iife模式吗?(不需要提供向后兼容性….)

    2 回复  |  直到 6 年前
        1
  •  1
  •   jfriend00    6 年前

    在我的代码中,几乎所有使用IIFE的常见原因都被块范围的变量所代替。

    我在实际代码中看到的一个用途是模拟顶级 await :

    (async function() {
        try {
            const data1 = await something1();
            const data2 = await something2(data1);
            ...
         } catch(e) {
            ...
         }
    })();
    

    我认为生命存在的其余原因是当你想要一个函数的优点,比如 return throw 停止执行剩余代码的定义部分(不在 if

    但是,如果函数中的代码从访问父作用域变量中受益匪浅,那么它确实希望是内联的,这就为IIFE结合在单独的函数中的优势和对父作用域的内联访问创造了一个可能的理由。

    现在,实际上,大多数/所有这些情况都可以通过一点重构来解决,要么在本地作用域中定义命名函数(这样它仍然可以访问父作用域变量),要么只是将东西从父作用域传递给命名函数,这样它就可以以这种方式访问它们,事实上,这也是我们在其他语言中所做的。这样做的唯一代价是多了一个本地函数名(如果要隐藏它,甚至可以对其进行本地作用域)。

        2
  •  3
  •   CertainPerformance    6 年前

    对于一个普通块不能实现的生命周期来说,一个好处是它的输出能够分配给 const . 例如:

    const output = (() => {
      // some calculations that take a few lines
      const now = new Date();
      return now.getMinutes() + ':' + now.getSeconds();
    })();
    console.log(output);

    假设我们想把 now 生活中的变量,因为它只与计算有关 output ,其他任何地方都不需要。如果我们使用一个普通的块来代替它,那么只有在 输出 被宣布 let 常量 :

    let output;
    {
      // some calculations that take a few lines
      const now = new Date();
      output = now.getMinutes() + ':' + now.getSeconds();
    }
    console.log(output);

    因为 显著地提高了代码的可读性(在我看来),这可能是一个更喜欢IIFE而不是普通块的潜在原因,尽管代码样式当然不同。

    也就是说,如果有人 extract till you drop ,有些人可能会说,为了避免IIFEs并声明一个独立的函数,然后可以导入并调用该函数:

    function getTimeStr() {
      const now = new Date();
      return now.getMinutes() + ':' + now.getSeconds();
    }
    
    // another file:
    // import getTimeStr from './getTimeStr';
    const output = getTimeStr();
    console.log(output);