Javascript学习笔记:闭包题解(1)
代码:
1 function createFunctions(){ 2 var result=[]; 3 for(var i=0;i<10;i++){ 4 result[i]=function(){ 5 return i; 6 }; 7 } 8 return result; 9 } 10 11 var funcs=createFunctions(); 12 console.log(funcs[0]());
问题:请写出该段代码打印出的结果。
正确答案:10
解析:闭包保存的是包含函数的作用域链,而不是具体的某个变量的具体的值。作用域链本质上是一个指向变量对象的指针列表,它只引用但不实际包含变量对象。因此在本题中,createFunctions返回的10个闭包中的i,指向的是createFunctions中的i,仅只是指向,而不是保存的固定的值。当返回的闭包函数运行时,i这个变量的值已经变更为10,所以最后的打印结果为10。要想实现每个闭包返回闭包创建时的i的值的效果,这段代码可以这么改:
1 function createFunctions(){ 2 var result=[]; 3 for(var i=0;i<10;i++){ 4 result[i]=(function(num){ 5 return function(){ 6 return num; 7 }; 8 })(i); 9 } 10 return result; 11 } 12 13 var funcs=createFunctions(); 14 console.log(funcs[0]());//0 15 console.log(funcs[5]());//5 16 console.log(funcs[9]());//9
或者可以使用ES6中的let实现,只需要将题目中的for循环中的var改成let就可以了,let是块级作用域。
1 'use strict'; 2 3 function createFunctions(){ 4 var result=[]; 5 for(let i=0;i<10;i++){ 6 result[i]=function(){ 7 return i; 8 }; 9 } 10 return result; 11 } 12 13 var funcs=createFunctions(); 14 console.log(funcs[0]());//0