尝试使用闭包和let:
在for循环中打印一系列数字考虑以下示例:
for(var i=1; i<10; i++){
setTimeout(function(){
document.write(i);
}, 1000);
}
输出是:
101010101010101010
关闭:
for(var i=1; i<10; i++){
(function(x){
setTimeout(function(){
document.write(x);
}, 1000);
})(i);
}
输出是:
123456789
没有关闭,只需使用ES6即可:
for(let i=1; i<10; i++){
setTimeout(function(){
document.write(i);
}, 1000);
}
输出是:
123456789
试图了解我们是否仍然需要使用IIFE块来关闭ES6?
如果我们确实需要使用ES6进行闭包,那还有什么好的例子吗?
答案 0 :(得分:5)
let
为块声明范围中的名称绑定用它声明的变量。您可以阅读标准文档中的语义。
如果您有let
,请使用它。否则使用IIFE或重写代码以避免需要。
答案 1 :(得分:5)
以下是Kleo Petrov的一个很好的解释 -
Do ES6 Modules make the case of IIFEs obsolete?
IIFE是ES5中使用最多的模式之一,因为函数是声明范围代码块的唯一方法。在ES6中,我们可以使用模块来代替使用IIFE:
// myModule.js
let counter = 0;
export function increment() {
counter++;
}
// logic.js
import {increment} from 'myModule.js';
increment();
您可能希望在ES6中使用IIFE的唯一情况是使用立即调用的箭头函数,这需要多个表达式,例如:
const SENTENCE = 'Hello world, how are you?';
const REVERSE = (() => {
const array = [...SENTENCE];
array.reverse();
return arr.join('');
})();
答案 2 :(得分:4)
使用闭包的一个简单例子,我记得,是一个计数器:
function makeCounter() {
let currentCount = 1;
return function() {
return currentCount++;
};
}
let counter = makeCounter();
console.log( counter() ); // 1
console.log( counter() ); // 2
console.log( counter() ); // 3
答案 3 :(得分:1)
当您想要使用在每次迭代中在循环中重新分配的变量的值时,这个特殊用例确实通过新的Es6块范围进行了简化。
在Get the API key上的最新N. Zachas书中对此行为进行了非常好的评论(整本书是一本非常好的读物,如果你打算用它作为一个主要参考)。
至于使用新语法的示例可能是新的最佳实践,因为它会导致预期的行为,而旧的for(var i = 0; i < length; i++){}
语法则令人困惑。
但请记住,您可能希望使用Babel或Tracer将代码转换为es5。在这种情况下,这些工具用于模拟块作用域的方式是使用闭包。因此,为了完成和调试目的,你可能应理解该模式。
书籍github
中的示例的转录示例