Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/406.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么使用IFFE闭包而不是常规闭包?_Javascript_Closures - Fatal编程技术网

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

Javascript 为什么使用IFFE闭包而不是常规闭包?,javascript,closures,Javascript,Closures,这两个闭包示例都有在后续函数调用中保留count值的好处,否则(如果未使用闭包),每次函数调用后count将重置为0。此外,在这两种情况下,count变量(与块中的任何let变量一样)都是私有的,也就是说,不能全局访问 IFFE闭包示例改编自马吕斯·舒尔茨(Marius Schulz),他在其中提出了该用法。我能想到的使用IFFE版本的闭包比常规版本的闭包的唯一优点是,您不必命名它(您只需将它分配给一个变量,以便再次调用它),或者如果您命名了它,它将在全局范围内不可见,因此可以减少一个污染全局命

这两个闭包示例都有在后续函数调用中保留count值的好处,否则(如果未使用闭包),每次函数调用后count将重置为0。此外,在这两种情况下,count变量(与块中的任何let变量一样)都是私有的,也就是说,不能全局访问

IFFE闭包示例改编自马吕斯·舒尔茨(Marius Schulz),他在其中提出了该用法。我能想到的使用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
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
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
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
如果关闭:

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

编辑:标记为重复的问题是另一个问题,选择的答案不回答此问题

不同之处在于IIFE闭包只能使用一次,而第一个闭包可以在需要时调用以生成新的迭代器,有点像生成器

例如,如果有一个排序队列要按需迭代,则可以使用第二个IIFE版本,但如果有两个队列,则可以调用
countingFunction
两次以创建单独的计数器

但是,如果你只需要一个这样的计数器,你可以把它包装成一个生命,以明确它将被使用一次,而且只被使用一次,并避免创建一个不再使用的变量。(这对脚本优化不是很有用,而是对可读性很有用)

旁注-更一致地命名变量可能会更清晰一些,因为第一个
countingFunction
与第二个
countingFunction
有很大不同。第一个调用时,会创建一些重要的东西,第二个则是重要的东西。可以调用第一个
makeCounter
和第二个
counter

常规关闭:

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
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
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
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
如果关闭:

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

可能是帕特里克的复制品,我昨天问了这个问题。这不是问同样的问题(而且选择的答案并不回答这个问题);将第一个函数的名称更改为createCounter。