说到闭包官方的解释太过于令人费解。
本人感觉闭包本质就是能够读取其他函数内部变量的函数。
一般情况下我们是不能通过一个函数读取另一个函数内部定义的变量的值。
function f1(){
var n=999;
function f2(){
var m = 1 ;alert(n); // 999
}
}
但是: 如上写法: 函数f2 就可以访问函数f1内部定义的变量值。
反过来,函数f1却不能访问f2内部定义的变量m,这就是JavaScript的链式作用域。
子对象会一级一级向上寻找对应变量,若找到则返回,否则报空,反之则不行。
此时,只需要把函数f2作为对象整体返回就可以在f1外部获取其内部定义的变量值。
需要注意的时,使用闭包后,由于作用域链的原因,数据可范围,并保持在内存中,不会被销毁。
function f1(){
var n=999;
nAdd=function(){n+=1}
function f2(){
alert(n);
}
return f2;
}
(1)var result=f1();
(2)result(); //alert 999
(3)nAdd(); // 执行方法+1
(4)result(); // alert 1000
1. 首先将函数f1 赋值给对象
2.执行对象方法 此时n = 999 此时nAdd函数在f1内部只是完成定义,但并没有执行,它也是一个闭包
3. 执行n+1 1000
4. 再次执行alert 1000
result 实际上就是闭包f2函数
可知:闭包会在上级函数外部,通过调用子函数,改变上级函数内部定义的局部变量。相当于getter/setter方法
网上有个比较经典的题,借此说明一下,帮助理解
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return this.name;
};
}
};
alert(object.getNameFunc()());
这里的getNameDunc 属性值有:匿名函数返回值决定(此时返回值对象是定义的函数,而非函数的结果)
因此this-->window 导致 object.getNameFunc()() 相当于 window.name 即 The Window
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
var that = this;
return function(){
return that.name;
};
}
};
alert(object.getNameFunc()());
此段代码:this--> object 由于 var that = this 导致 that中保存有object对象的上下文
所以getNameFunc属性:匿名函数返回值对象(也是函数,非函数结果),由于闭包函数保存有object上下文
因此object.getNameFunc()() 相当于调用 object.name 即 My Object
this 指向由自身所在函数调用的上下文环境决定。