之前看一个讲解闭包的博客,针对其中举的栗子,我觉得可以更加深入地去剖析,从而方便更多的人去理解闭包的概念:
就如那个博主所说:什么是闭包?有权访问另一个函数作用域内变量的函数都是闭包。
下面是栗子,认真看一分钟然后想一下结果是什么:
function createFunctions(){ var result = new Array(); for (var i=0; i < 10; i++){ result[i] = function(){ return i; }; } return result; } var funcs = createFunctions(); for (var i=0; i < funcs.length; i++){ console.log(funcs[i]()); }
如果你已经有了答案,那么带着你的答案,接着往下看。
1.改变上面的写法
function createFunctions(){ var result = new Array(); for (var i=0; i < 10; i++){ result[i] = function(){ return i; }; } return result; } var funcs = createFunctions(); for (var j=0; j < funcs.length; j++){ console.log(funcs[j]()); }
可以看到,我将下面的i改成了j,这是为了防止对函数作用域不清楚而混淆了这两个i。
2.解析createFunctions这个函数
其实这个函数看一眼就知道会返回一个变量result,那么这个变量是什么?
然后往回看,哦,是一个数组,那数组项是什么?
再往下看,哦,result[0]=function(){return i;}、result[1]=function(){return i;}........result[9]=function(){return i;}
简单来说,这就是一个函数数组,每一项都是一个函数,
3.funcs变量
函数只有带()才会执行,var funcs = createFunctions(),显然在为funcs的赋值的同时,createFunctions这个函数执行了;
然后注意了,在createFunctions这个函数执行了之后,变量 i 现在值是多少?没错,此时i=10。
于是,现在funcs就等于result,而result就是一个函数数组,此时 i =10.
4.执行funcs数组各项
既然funcs是一个数组,那么自然可以遍历数组项啊,由于数组项都是一个函数,那么就可以通过funcs[j]()来执行它
于是,在第二个for循环里面,依次执行了了每个数组项(的方法)
然而,数组项的方法是return i;于是funcs[1]()执行后返回 i,i是多少啊?i是10,嗯,对了,真聪明,
于是每一项都是执行这个方法(返回i的值),所以没一项都是返回10!!!