这个循环如何在Es5 / Es6上运行?

时间:2015-07-01 09:59:30

标签: javascript ecmascript-6 ecmascript-5

所以,试着学习一下ES6,我来到了这个链接,http://es6-features.org/#BlockScopedVariables

// ES6

let callbacks = []
for (let i = 0; i <= 2; i++) {
    callbacks[i] = function () { return i * 2 }
}
callbacks[0]() === 0
callbacks[1]() === 2
callbacks[2]() === 4

// ES5

var callbacks = [];
for (var i = 0; i <= 2; i++) {
    (function (i) {
        callbacks[i] = function() { return i * 2; };
    })(i);
}
callbacks[0]() === 0;
callbacks[1]() === 2;
callbacks[2]() === 4;

我可以知道为什么在ES5方法中我们使用立即函数来返回i * 2值吗?

但是在ES6中,只是在循环中分配值有效吗?

基本上,

  1. 想知道为什么会出现这种差异?
  2. 该循环如何执行?
  3. 我发现差异是由于“块范围(let)和全局范围(var)”,但是想了解有关执行/运行时点的更多信息?
  4. 所以我们不想在ES6中使用立即函数来保存变量的当前状态吗?

1 个答案:

答案 0 :(得分:4)

正如您所说,区别在于使用let创建块范围变量与使用var创建执行上下文范围变量 - 不仅仅是全局变量但是执行功能的范围。

// ES6
var callbacks = [];
for (let i = 0; i <= 2; i++) {
    // A new LexicalEnvironment is established here, where i only survives
    // the duration of this 'for' statement
    // So we can safely say that when function() is called, `i` will have
    // the value we assign to it here
    callbacks[i] = function () { return i * 2 }
}

然而,在ES5 ......

// LexicalEnvironment is established here and `i` is declared
var callbacks = [];
for (var i = 0; i <= 2; i++) {
    callbacks[i] = function() { return i * 2; };
}
// `i` is still available now and its value is currently 2
// So when you execute `callbacks[2]()` the LexicalEnvironment where `i` was set
// is the one where i === 3
callbacks[0]() // 6
callbacks[1]() // 6
callbacks[2]() // 6

现在,在ES5中使用IIFE ......

var callbacks = [];
for (var i = 0; i <= 2; i++) {
    // Much like using let, by declaring an IIFE here, we are telling the engine
    // to create a new LexicalEnvironment to store the current value of i
    (function (i) {
        callbacks[i] = function() { return i * 2; };
    })(i);
}