闭包与ES6让

时间:2017-01-27 11:04:51

标签: javascript

尝试使用闭包和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进行闭包,那还有什么好的例子吗?

4 个答案:

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

中的示例的转录示例