今天同事问我一个问题,
function fun() {
var arr = [];
for (var i = 0; i < 10; i++) {
arr[i] = function() {
return i;
};
}
return arr;
}
console.log(fun()); //输出结果你认为是什么呢?
我还记得去年找工作前,看面经遇到过这道题,现在看来比初出茅庐那会更好理解了,这半年,说实话,就是从逛优快云后才开始慢慢成长的,记录自己问题,学习笔记,觉得接触新东西很有意思。言归正传~~~~
大家可以先自己推理下,然后再去控制台验证是否正确。我现在贴出控制台的输出。
控制台输出的是一个数组,数组中的元素都是 function
方法,这种情况下,仔细看一下上面的js片段,我们可以看到 arr[i]
里存入了函数,而且 return
了当时的 i
。但是,arr[i]中的函数并没有被调用,也就是只是把 function
依次存入,却并没有执行。
下面我们为 arr
中的方法传参让他们执行
function fun() {
var arr = [];
for (var i = 0; i < 10; i++) {
arr[i] = function() {
return i;
};
}
return arr;
}
var a = fun();
console.log(a[1]()); // 10
console.log(a[2]()); // 10
我们可以看到,无论我们掉得是第几个方法,返回的只有 10
。因为每个函数的作用域链中都保存着 fun()
函数的活动对象,所以他们引用的都是同一个 i
,当最后调用函数的时候,循环已经结束, i
的值为 10
,所以都返回 10
。
那如果我们想要依次得到每个 i
该如何做呢?
第一种方法:当然是调用 arr
里的函数方法啦!
function fun() {
var arr = [];
for (var i = 0; i < 10; i++) {
arr[i] = function() {
return i;
}();
}
return arr;
}
console.log(fun()); // [0,1,2,3,4,5,6,7,8,9]
仔细观察在 arr[i]
的最后,我用 ()
进行了自调,这时候函数就会执行,并 return
当时的 i
。
这个时候的输出结果为:(按序输出 i
)
第二种方法:采用es6的let
function fun() {
var arr = [];
for (let i = 0; i < 10; i++) {
arr[i] = function() {
return i;
};
}
return arr;
}
var a = fun(); // [function(){..},...,function(){..}]
console.log(a[1]()); // 1
console.log(a[4]()); // 4
今天看完了上周开始看的一本书,所以晚上终于有时间更新下啦。最近上班时间也是比较忙,整理知识的过程可真是有趣呀,哈哈哈哈啊哈。我发现我也写的越来越规整了。有进步少年。