var a = [] var i = new Number(0); console.log(i.id());// 0 for(; i < 10; i = new Number(i+1),i.id()){ (function(i){ a[i] = function(){ console.log(i.id()); console.log(i.toString()); } })(i); a[6](); // 6 6 a[7](); // 7 7 a[8](); // 8 8 a[9](); // 9 9 console.log(i.id());// 10 }
由于这个立即执行函数引用着数值0~9,当我们执行函数a[i]的时候,会顺着作用域链先找到这个立即执行函数的作用域.立即执行函数维护着0~9的数值引用,我们就可以在函数a[i]中正确的输出i的值.通过执行结果,我们可以看到,不光执行结果是对的,同时我们引用的值的相对内存地址也都是对的.接着我们把原来为了测试显式声明的Number对象改回去.如下:
var a = []; for(var i = 0; i < 10; i++){ (function(i){ a[i] = function(){ console.log(i); } })(i); }
最后我们再来看看ES6的语法中推荐用let代替var以及经过bable编译生成ES5的代码是如何的:
//ES6代码 var a = [] for(let i = 0; i < 10; i++){ a[i] = function(){ console.log(i); } } a[6](); //babel编译生成的ES5代码 "use strict"; var a = []; var _loop = function _loop(i) { a[i] = function () { console.log(i); }; }; for (var i = 0; i < 10; i++) { _loop(i); } a[6]();
看~我们的解决方法和ES6的解决方法是不是很像.这里我们的立即执行函数相当于生成的ES5代码中的_loop函数以及_loop(i)的执行.
您可能感兴趣的文章: