这个循环如何在 Es5/Es6 上工作?
How does this loop work on Es5/Es6?
所以,为了学习一些关于 ES6 的知识,我来到这里 link,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 方法中我们使用立即函数来 return i*2 值吗?
但是在 ES6 中,只在循环中赋值就可以了吗?
基本上,
- 想知道为什么会出现这种差异?
- 该循环是如何执行的?
- 我发现差异是由于 "block scope (let) & global scope (var)",但想了解更多关于 execution/runtime 点的信息?
- 所以我们不想在 ES6 中使用立即函数来保存变量的当前状态?
如您所说,区别在于使用 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);
}
所以,为了学习一些关于 ES6 的知识,我来到这里 link,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 方法中我们使用立即函数来 return i*2 值吗?
但是在 ES6 中,只在循环中赋值就可以了吗?
基本上,
- 想知道为什么会出现这种差异?
- 该循环是如何执行的?
- 我发现差异是由于 "block scope (let) & global scope (var)",但想了解更多关于 execution/runtime 点的信息?
- 所以我们不想在 ES6 中使用立即函数来保存变量的当前状态?
如您所说,区别在于使用 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);
}