这两个闭包示例都具有在后续函数调用中保留count值的好处,而否则(如果未使用闭包),则每次函数调用后count都将重置为0。此外,在这两种情况下,count变量(作为块中的任何let变量)都是私有的,即不可全局访问。
IFFE闭包示例改编自Marius Schulz的article,他在其中提出了这种用法。我可以想到的是,使用IFFE版本的闭包而不是常规版本的唯一好处是,不必命名它(只需将其分配给变量即可再次调用它),或者您确实要为其命名,它将在全局范围内不可见-因此,有少一个污染全局名称空间的项目。我还有其他好处吗?
常规关闭:
function createCounter() {
let count = 0;
return function() {
++count;
return `count equals ${count}`;
};
};
let counter = createCounter();
console.log(counter()); // count equals 1
console.log(counter()); // count equals 2
IFFE关闭:
let countingFunction = (function() {
let count = 0;
return function() {
++count;
return `count equals ${count}`;
};
})();
console.log(countingFunction()); // count equals 1
console.log(countingFunction()); // count equals 2
编辑:标记为重复的问题是一个不同的问题,并且所选答案未回答该问题。
答案 0 :(得分:4)
区别在于IIFE闭包只能在一次中使用,而第一个闭包可以在需要时调用以创建新的迭代器,就像生成器一样。
例如,如果您有一个一个队列想要按需进行遍历,则可以使用第二个IIFE版本,但是如果您有两个队列,您可以致电countingFunction
两次来创建单独的计数器。
但是,如果您只需要一个这样的计数器,则可以将其包装为IIFE,以明确表示它将仅使用一次,并且只能使用一次,并避免创建不会使用的变量。再次。 (这对脚本优化不是很有用,但对可读性却有用)
旁注-更一致地命名变量可能会更清楚一点,因为第一个countingFunction
与第二个countingFunction
完全不同。第一个被调用时,创建很重要,第二个是重要。也许叫第一个makeCounter
和第二个counter
:
常规关闭:
function makeCounter() {
let count = 0;
return function() {
++count;
return `count equals ${count}`;
};
};
let counter = makeCounter();
console.log(counter()); // count equals 1
console.log(counter()); // count equals 2
IFFE关闭:
let counter = (function() {
let count = 0;
return function() {
++count;
return `count equals ${count}`;
};
})();
console.log(counter()); // count equals 1
console.log(counter()); // count equals 2