关于闭包

当函数执行完毕时,管理内存的本地方法会将函数中所有创建了的东西从内存中移除。因为函数已经执行完毕,所以我们似乎不再需要访问该执行内存中的任何东西了。

1
2
3
(function(){
var prisoner = 'Jsoh';
})();

一旦函数执行完成,prisoner变量就不再需要保存在内存中了。

1
2
3
4
5
6
7
8
var prison = (function(){
var prisoner = 'Jsoh';

return{prisoner:prisoner};
})();

//"Jsoh"
console.log(prison.prisoner);

我们仍然不需要在匿名函数执行后访问prisoner变量。因为字符串Jsoh已经保存在prison.prisoner中,没有理由再在模块所在的内存中保存prisoner变量,因为它不用再被访问。prison.prisoner的值是字符串Jsoh,但是它不再指向prisoner变量。

1
2
3
4
5
6
7
8
9
10
11
12
var prison = (function(){
var prisoner = 'Jsoh';

return{
prisoner:function(){
return prisoner;
}
}
})();

//"Jsoh"
console.log(prison.prisoner());

现在,每次执行prison.prisoner时都会访问prisoner变量。prison.prisoner()返回prisoner变量的当前值。如果垃圾回收器来把它从内存中移除了,调用prison.prisoner会返回undefined,而不是Jsoh。

所以什么是闭包?闭包是阻止垃圾回收器将变量从内存中移除的方法,使得在创建变量的执行环境的外面能够访问到该变量。当prisoner函数被保存到prison对象上时,一个闭包就创建了。闭包因保存函数而被创建,在执行函数的外面,可以动态访问prisoner的值,这就阻止了垃圾回收器将prisoner变量从内存中移除。

下面我们来看一段代码复习一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var prison = (function(){
var prisoner_name = 'Mike';
jail_term = '20 year term';

return{
prisoner: function(){
return prisoner_name + ' - ' + jail_term;
}
setJailTerm: function(term){
jail_term = term;
}
};
})()

//"Mike - 20 year term"
console.log(prison.prisoner());

prison.setJailTerm('Sentence commuted');
//"Mike - Sentence commuted"
console.log(prison.prisoner());