初学闭包,有下面的疑惑,希望得到高人的指点
第一种形式:
var result = new Array();
function createFunctions(){
for(var i=0;i<10;i++){
result[i] = function(){
return i;
};
}
return result;
}
createFunctions();
for(var i=0;i<result.length;i++){
alert(result[i]());
}//结果每个都是10.
改进后:
var result = new Array();
function createFunctions(){
for(var i=0;i<10;i++){
result[i] = function(){
return i;
}();
}
return result;
}
createFunctions();
for(var i=0;i<result.length;i++){
alert(result[i]);
}
//结果是0-9
那我的问题就是这个算是用闭包解决的吗?内部函数可以访问外部的变量。
再一次修改为:
var result = new Array();
function createFunction(){
for(var i=0;i<10;i++){
result[i] = function(num){
return function(){
return num;
};
}(i);
}
return result;
}
createFunction();
for(var i=0;i<result.length;i++){
alert(result[i]());
}
这个是书的用闭包解决最初的问题,我想第二个可以实现,为什么要这么复杂的写法呢?是不我理解的闭包还是有问题,还不知道闭包要是用在哪?
JS中变量只有函数作用域
JS中变量为词法作用域,也就是变量在声明的时候就确定其作用域
闭包其实是扩展了函数的作用域链,函数可以使用在其外层函数中声明的变量
你的2中写法实现的目的不同,导致实现的方式的差异
第1中方式:result中保存的是一个结果
第2中方式 result中保存的是一个函数对象,其具有再次执行的能力
看你想要的结果是什么,就用什么样的实现~~~
在回答你这个问题前,说一说闭包。
是之前我给我们公司培训前端知识的时候整理的一些内容,选取其中的部分:
其实,你两种方式是差不多的。一种是通过直接访问外部变量(第一种),还有一种是通过参数形式(第二种)。从访问外部变量的角度看,第二种其实没有形成闭包。如果从作用域的角度看,第二种属于闭包。
其实,这些概念性的东西,不要纠结太多,主要是你要有自己的理解。
虽然形式都看似差不多,甚至如你认为的那样,第一种更简洁,孰优孰劣(不仅仅要从书写代码的层面上考虑,上面也提到了一个内存泄露的东西),你可以去多看下,多了解下。
这里,我推荐第二种方式。
你的方法是把值直接输出。看似效果一致,其实并不是闭包。闭包是从外部访问局部变量,得到的值是通过内部return出来的函数去通过作用域访问到想要的局部变量,书上的那个方法是访问每一次循环的i变量,所以有十个外层函数定义的不一样的i,被return 的十个函数从外部访问,所以需要用result[i]()调用函数获取,而不是固定下来的值。
首先解释一下第一段函数为什么都输出十,因为这段代码运行中会形成闭包
用到了它的父函数所定义的变量(也就是for中声明的),在这个函数没有结束之前变量并不会被销毁,会得到保留,所以说i的值一直被保留直到完全运行完,所以十个值全都是十。
第二段函数个人认为是解决了闭包的问题,利用了自执行,没次返回后函数会自动立即执行,故可以把i的值实时的送出去。
本人水平有待提高,说的不是很清楚,希望可以对你有用