前言:
闭包(closure)是Javascript语言的一个难点,也是它的特点,不少高级应用都要依靠闭包实现。
要理解闭包,首先必须理解Javascript特殊的变量做用域。
变量的做用域无非就是两种:全局变量和局部变量。
Javascript语言的特殊之处,就在于函数内部能够直接读取全局变量。
1. 关于全局变量 和 局部变量的 理解:
函数外面: var a = 20; 此处var声明的a是一个全局变量
函数内部:function getAll() {
//若是是 var 声明的,则是局部变量 (与函数外面声明的相反 )
var a = 20;
//若是是直接写的(省去var声明的),则是全局变量
a = 20
}
访问范围:
全局变量,在整个script中,均可以访问到;
可是局部变量只能在函数内部访问到;函数外部是不能访问到的。
有时候,想要在全局访问到函数内部的局部变量,要怎么办?
——闭包,能够实现这一点。
2. 闭包(closure):
何为闭包?
在一个函数中写入另一个函数,而且能够访问到这个函数的局部变量的函数,这就是闭包。
在js中,只有一个函数内部的子函数才能够读取局部变量,因此,也能够把闭包理解为“定义在一个函数内部的函数”。
(本质上,闭包就是讲函数内部和函数外部连接的一座桥梁。)
function fn1(){
var a = 20;
return function fn2(){
alert(a);
}
}
fn1()();
此处的 fn2函数就是闭包函数。
3. 闭包的做用:
第一:能够读取一个函数内部的函数,
第二:避免“垃圾回收机制”回收,由于子函数会返回一个全局变量,又会调用父函数的局部变量,两个变量相互调用;
因此,两个函数都不会被清除。
四、关于闭包中this的指向问题( 进阶版)。
代码一:
var name = 'The window ';
var object = {
name: ' my object',
fn1 : function(){
alert('1' + this.name); //此处this.name为 my object (由于会继承object)
return function(){
alert('2' + this.name); //此处this.name为The window (没有执行是上下文,因此,找到了windows )
return this.name;
}
}
}
object.fn1()();
难点:红色部分打印出来的为何是“The window” ?
解释:
咱们能够换种写法:
var obj = object.fn1()();
obj();
这里的obj()是函数体 function() { return this.name };
此处的obj指向的是window,因此this.name是The.window
代码二:
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
var that = this;
alert(that.name); //?
return function(){
alert(this.name); //?
alert(that.name); //?
return that.name;
};
}
};
object.getNameFunc()();
解释:这里只要是that.name都是指向的“My Object”;
由于,红色的那行代码,把this的指向作了保存。
可是若是用的是,this.name依然指向的是windows(能够参考代码一中的解释)。