初学闭包,有下面的疑惑,希望得到高人的指点
第一种形式:
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]());
}
这个是书的用闭包解决最初的问题,我想第二个可以实现,为什么要这么复杂的写法呢?是不我理解的闭包还是有问题,还不知道闭包要是用在哪?
你的方法是把值直接输出。看似效果一致,其实并不是闭包。闭包是从外部访问局部变量,得到的值是通过内部return出来的函数去通过作用域访问到想要的局部变量,书上的那个方法是访问每一次循环的i变量,所以有十个外层函数定义的不一样的i,被return 的十个函数从外部访问,所以需要用result[i]()调用函数获取,而不是固定下来的值。
JS中变量只有函数作用域
JS中变量为词法作用域,也就是变量在声明的时候就确定其作用域
闭包其实是扩展了函数的作用域链,函数可以使用在其外层函数中声明的变量
你的2中写法实现的目的不同,导致实现的方式的差异
第1中方式:result中保存的是一个结果
第2中方式 result中保存的是一个函数对象,其具有再次执行的能力
看你想要的结果是什么,就用什么样的实现~~~
var result = new Array();
function createFunction(){
for(var i=0;i<10;i++){
result[i] = function(num){
return function(plus){
return num+plus;
};
}(i);
}
return result;
}
createFunction();
for(var i=0;i<result.length;i++){
console.log(result[i](i));
}
首先解释一下第一段函数为什么都输出十,因为这段代码运行中会形成闭包
result[i] = function(){
return i;
用到了它的父函数所定义的变量(也就是for中声明的),在这个函数没有结束之前变量并不会被销毁,会得到保留,所以说i的值一直被保留直到完全运行完,所以十个值全都是十。
第二段函数个人认为是解决了闭包的问题,利用了自执行,没次返回后函数会自动立即执行,故可以把i的值实时的送出去。
本人水平有待提高,说的不是很清楚,希望可以对你有用
在回答你这个问题前,说一说闭包。
是之前我给我们公司培训前端知识的时候整理的一些内容,选取其中的部分:
有人说,函数就是“闭包”;
也有人说,闭包是函数的“堆栈”;
还有人说,闭包是一种特殊的对象;
我说,闭包-定义了一个作用域。
(function(){
//
})();//我不知道这是不是闭包,我当做是
function fun(){
//
};//这是函数,其实不是闭包
闭包-知乎说法
闭包-闭包是指在javascript中,内部函数总是可以访问其所在外部函数中声明的参数和变量,即使在其外部函数被返回(寿终正寝)了之后。
我又换一种说法-一个函数将其内部变量(属性、方法)返回,使得可以外部访问,就是构成了闭包。
闭包是魔鬼
刚刚看到的“寿终正寝”之后,依然可以访问,糟糕,内存泄露的问题来了。
很多人把问题归结于闭包,其实是不对的,很大程度上跟自己写的代码有关(网上有相关资料)
闭包是天使
闭包不是魔鬼,其实是长着魔鬼脸的天使
闭包是一些函数型编程语言的特性
闭包允许财产私有化(下面会说私有属性/方法)
闭包对于模块化有大恩大德
其实,你两种方式是差不多的。一种是通过直接访问外部变量(第一种),还有一种是通过参数形式(第二种)。从访问外部变量的角度看,第二种其实没有形成闭包。如果从作用域的角度看,第二种属于闭包。
其实,这些概念性的东西,不要纠结太多,主要是你要有自己的理解。
虽然形式都看似差不多,甚至如你认为的那样,第一种更简洁,孰优孰劣(不仅仅要从书写代码的层面上考虑,上面也提到了一个内存泄露的东西),你可以去多看下,多了解下。
这里,我推荐第二种方式。