最近看了一些关于闭包的内容,自己总结了一下:
闭包其实就是内部函数调用外部函数的变量,使变量一直存在于内存中.
内部函数是一个匿名函数
先给大家看一个例子:
function getFunction(){
var result = new Array();
for(var i=0;i<10;i++){
result[i] = function(){
alert(i);
}
}
return result;
}
var result1 = getFunction();
for(var j=0;j<10;j++){
result1[j]();
}
可能大家的理想结果是当i=0 输出0 i=1 输出1 但是结果并不是,结果是输出的结果都是10。
为什么会导致这个结果,我们从作用域链的角度进行分析:
下面都是个人理解,欢迎大家指出错误:
每一个内部函数都会保存着属于自己的作用域链,而它自己的作用域链包括了自己的活动对象,外部函数的活动对象,全局的
活动对象,当查找变量时会逐级查找,分析上面内部函数的作用域链:
内部函数的活动对象有:arguments=null this = window(如果不指定this,内部函数this将为window)
外部函数的活动对象有:arguments=null this=getFunction result(new Array()) i=10
全局函数的活动对象有:result1=undefined this = window getFunction-->getFunction的作用域链
通过上面对活动对象的分析:
当调用内部函数时,获取的i永远为10;
那么我们将如何解决,方法如下:
function getFunction(){
var result = new Array();
for(var i=0;i<10;i++){
result[i] = function(num){
return function(){
alert(num);
};
}(i);
}
return result;
}
var result1 = getFunction();
for(var i=0;i<10;i++){
result1[i]();
}
内部函数的活动对象有:arguments=null this = window(如果不指定this,内部函数this将为window)
外部函数1的活动对象有:arguments[num] this=window(如果不指定this,内部函数this将为window) num(保存着1-9)
外部函数2的活动对象有:arguments=null this=getFunction result(new Array()) i=10
全局函数的活动对象有:result1=undefined this = window getFunction-->getFunction的作用域链
所以当调用时,找到num,所以会输出正常.
理解下面的例子:
var name = "The Window";
var Person = {
name : "Person name",
getName :function(){
return function(){
return this.name;
}
}
};
alert(Person.getName()());
输出的结果是 "The Window" ,下面是对结果的分析:
内部函数查找arguments和this两个变量时,只会查找到其当前活动对象为止
分析活动对象:
内部函数的活动对象有:this=window arguments=null
所以此时this=window,相当于调用window.name,所以输出为"The Window"
那怎样才能让其输出为"Person name":
var name = "The Window";
var Person = {
name : "Person name",
getName :function(){
that = this;
return function(){
return that.name;
}
}
};
alert(Person.getName()());
输出结果是 "Person name",下面是对结果的分析:
分析活动对象:
内部函数的活动对象有:this=window arguments=null
外部函数的活动对象有:this=Person arguments=null that=this
所以当调用that.name时会返回"Person name";