为什么使用IFFE闭包而不是常规闭包?

时间:2018-06-22 02:44:49

标签: javascript closures

这两个闭包示例都具有在后续函数调用中保留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

编辑:标记为重复的问题是一个不同的问题,并且所选答案未回答该问题。

1 个答案:

答案 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