最近我试图在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)相同。有点困惑......
答案 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
现在等于counter
,count
能够保留对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变量声明为函数本身。
以这种方式思考(也可以在控制台中尝试查看结果)。
(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