在了解一定闭包知识的基础上,再来一个题:
function test(){
var arr = [];
for(var i = 0; i < 10; i++){
arr[i] = function(){
document.write(i + " ");
}
}
return arr;
}
var myArr = test();
for(var j = 0; j < 10; j++){
myArr[j]();
}
试试猜测结果。
分析: 一看return,闭包,没跑了。跟着test里面的i走就完事了,一个递增 0 1 2 3 4 5 6 7 8 9
美滋滋
但是我们发现又错了(;′⌒`)
原因:在执行 var myArr = test()的时候,只执行了test()函数,也就是说,在返回出来的myArr数组中,每一位就是一个函数,具体是啥函数,不知道。直到myArrj的时候,里面的documen.write才执行,那时i的值是从test的AO里找到的,再循环之后i 的值是10,所以最后的结果: 10 10 10 10 10 10 10 10 10 10 。
知道原因还不够,我们如果想要一开始的结果,我们就得解决他。
首先:飘逸解决法:
function test(){
var arr = [];
for(var i = 0; i < 10; i++){
arr[i] =i
}
return arr;
}
var myArr = test();
for(var i = 0; i < 10; i++)
{
document.write(myArr[i]);
}
直接顺着循环赋值,最后调用时再打印。
但是我们本着深度学习的目的,这种方法显然不是我们想要的。就是想在test函数里调用打印,怎么办?
function test(){
var arr = [];
for(var i = 0; i < 10; i++){
( function(j){
arr[j] = function(){
document.write(j + ' ');
}
}(i));
}
return arr;
}
var myArr = test();
for(var k = 0; k < 10; k++){
myArr[k]();
}
分析:
首先我们能看到(function (j){}())立即执行函数。
for 中i作为实参传进,arr….每次执行都能拿到外部(立即执行函数)的AO,所以每次在for循环里递增的i会被保存到立即执行函数的作用域里,从而被里层函数所调用,实现递增打印。
感谢访问!