【问题标题】:Difference between an IIFE and non-IIFE in JavaScript Modular approachJavaScript模块化方法中IIFE和非IIFE之间的区别
【发布时间】:2016-02-06 05:37:57
【问题描述】:

最近我在尝试更多地了解 IIFE 和 JavaScript 中的模块 我想到了一个问题,IIFE 如何在不立即制作模块的情况下制作模块 调用该函数不会使其成为一个模块..

谁能和我分享这段代码的区别

var MODULE = (function () {
var my = {},
    privateVariable = 1;

function privateMethod() {
    // ...
}

my.moduleProperty = 1;
my.moduleMethod = function () {
    // ...
};

return my;
}());

以及这个函数没有立即调用的代码..

var MODULE = function () {
var my = {},
    privateVariable = 1;

function privateMethod() {
    // ...
}

my.moduleProperty = 1;
my.moduleMethod = function () {
    // ...
};

return my;
};

第二段代码是否意味着Module只是一个本身返回对象的函数?

如果我像这样使用第二个变量

var ModuleObj = Module();

这会和我分享的第一个代码块一样工作吗?像 IIFE..有点困惑...

【问题讨论】:

    标签: javascript module iife


    【解决方案1】:

    是的,您已经大致了解了两者之间的区别,让我们看看为什么您可能想要其中一个而不是另一个。

    IIFE 可用于隔离范围。它可以让你在 IIFE 中保持你定义的私有变量,而不会污染它周围的全局空间。这是组合函数的好方法,该函数具有一些您不需要潜伏的变量。让我们把这个例子最小化一点。

    var Counter = (function () {
      var count = 0;
    
      var counter = {
        add: function () {
          count++;
        },
        subtract: function () {
          count--;
        },
        getCount: function () {
          return count;
        }
      }
      return counter;
    })();
    
    Counter.add();
    Counter.add();
    Counter.getCount(); // 2
    Counter.subtract();
    Counter.getCount(); // 1
    

    上面发生的情况是,我们能够在不泄露私人信息的情况下编写这个“计数器”功能,例如 count。如果其他东西可以意外覆盖它,那就太糟糕了。此外,我们可以立即将Counter 分配给IFFE 的result——counter 函数集。 Counter 现在等于那个值,并且 counter 能够保留对 count 的访问权限,因为它是在同一范围内定义的。

    这里的好处是我们能够为这个功能组合分配一个变量。 IIFE 基本上允许我们立即返回我们在其中的return。由于我们将 Counter 分配给 IIFE,而 IIFE 返回其中的功能,Counter 现在是一个功能齐全的组件。

    我们并不总是必须使用 IIFE。当您想要“隐藏”实现细节并返回 API 时,它真的很方便。


    那么,如果我们有同样的东西,但它不是一个 IIFE——只是一个函数呢?

    就像您的示例一样,我们必须调用它才能获得“实例”。

    var CounterFactory = function () {
      var count = 0;
      var counter = {
        add: //...
        subtract: //...
        getCount: //...
      };
      return counter;
    };
    
    var CounterA = CounterFactory();
    var CounterB = CounterFactory();
    
    CounterA.add();
    CounterA.add();
    CounterA.getCount(); // 2
    
    CounterB.add();
    CounterB.getCount(); // 1
    

    看到区别了吗?这都是关于函数返回的内容。在第一个示例中,我们只得到一个 Counter 实例,这可能非常好。在第二个示例中,它更像是一个“工厂”——它生成一个counterinstance,我们可以多次调用它并获取它的多个实例。

    【讨论】:

      【解决方案2】:

      好的,IIFE 运行其中的函数并将变量 MODULE 定义为该函数的返回值。另一个向函数本身声明 MODULE 变量。

      这样想(也可以在控制台中尝试以查看结果)。

      此代码不运行 console.log 方法。

      (function(){
          console.log('ran')
      });
      

      这段代码可以

      (function(){
          console.log('ran')
      })();
      

      所以 IIFE 的全部意义在于在执行任何操作之前运行函数以及 ();最后这样做。

      如果我们将没有运行的代码赋值给一个值会发生什么?

      var foo = (function(){
          console.log('ran')
      });
      foo();
      

      我们有一个可以执行的函数 foo。

      那么,如果我们可以分配 IIFE 并稍后运行它,那么它的意义何在?答案是局部变量,您可以稍后将其用于关闭。

      console.log(num); //get undefined
      (function(){
          var num = 'ran';
          console.log(num) //get 'ran'
      })();
      console.log(num); //get undefined
      

      我们得到 undefined run then undefined 所以我们在函数中声明的值保留在函数中,没有其他东西可以得到它们。这是 JavaScript 运行的词法范围。

      只是为了好玩,让我们用它做一个闭包。

      var add = (function(){
          var num = 0;
          return function(){
              console.log(num++);
          }
      })();
      console.log(num) //get undefined
      add() //get 1
      add() //get 2
      console.log(num) //still undefined
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-07-10
        • 1970-01-01
        • 2020-03-08
        • 2015-10-08
        • 2014-03-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多