JavaScript模块化方法中IIFE和非IIFE之间的区别

时间:2016-02-06 05:37:57

标签: javascript module iife

最近我试图在JavaScript中学习更多关于IIFE和模块的知识 我想到了一个问题,即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)相同。有点困惑......

2 个答案:

答案 0 :(得分:7)

是的,你几乎已经明白了两者之间的区别,让我们来看看为什么你可能想要一个而不是另一个。

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

上面发生的是我们能够组成这个" counter"功能,而不会泄露私人信息,如count。如果其他事情可能意外地超越它,那就太糟糕了。另外,我们可以立即将Counter分配给IFFE的结果 - counter函数集。 Counter现在等于countercount能够保留对return的访问权限,因为它是在同一范围内定义的。

这里的好处是我们能够为这个功能组合分配一个变量。 IIFE基本上允许我们立即返回我们Counter内部的内容。由于我们将Counter分配给IIFE,并且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 现在是一个功能齐全的组件。

我们不一定要使用IIFE。当你想要小心翼翼的时候,这真的很方便。实现细节并返回API。

那么,如果我们有同样的事情,但它不是一个IIFE - 只是一个功能呢?

就像你的例子一样,我们必须调用它才能获得"实例"。

Counter

看到区别?这完全取决于函数返回的内容。在第一个示例中,我们只获得一个counter实例,这可能非常好。在第二个例子中,它更像是一个"工厂" - 它生成until myserver; do echo "Server 'myserver' crashed with exit code $?. Respawning.." >&2 sleep 1 done 实例,我们可以多次调用它并获取它的多个实例。

答案 1 :(得分:1)

好的,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 ran然后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