一:什么是闭包
《JS高级程序设计》指出:闭包是指有有权访问另一个函数作用域中变量的函数。
二:闭包的使用
闭包的常见的创建方式是 子函数嵌套在父函数的内部,这样,子函数就可以访问父函数中的变量。
1 function add(){ 2 var a=1;
//暂且叫 innerAdd 函数 3 return function(){ 4 a++; 5 console.log(a); 6 } 7 } 8 add()(); 9 add()(); 10 console.log("------------------------"); 11 var addAfter=add(); 12 addAfter(); 13 addAfter();
8行---- 2
9行-----2
12,13行 ---2,3
那么,为什么第9行得到的结果仍然是2,而不是期待中的3呢?
这里因为JS里也有 C# Java里中的 垃圾回收 机制。
(1) 函数未被引用,执行完后,该函数作用域就会被回收。
(2)函数如果被其他变量引用,该函数作用域就会被保存下来。
第8,9行,add()函数并没有被其他变量引用,只是简单的执行,因此,a的作用域只存在该函数中。
11行,add()函数被外部变量 addAfter引用,函数中的a的值被保存在内存中。
可以这样说:如果innerAdd函数被父亲函数add之外的函数所引用,这样就形成了一个闭包,否则,是不能形成闭包的。
还有另外一种使用形式:
1 var addMatch=(function(){ 2 var a=22; 3 return function(){ 4 a++; 5 console.log(a); 6 } 7 })(); 8 addMatch(); 9 addMatch();
三:闭包的问题
闭包只能取得包含函数中的最后一个变量值,保存的是整个变量对象,而不是某个特殊的变量。
1 var arr1=[12,19,3],arr2=[],arrLength=arr1.length; 2 for(var i=0;i<arrLength;i++){ 3 arr2[i]=function(){ 4 console.log(i); 5 return i; 6 }; 7 }
四:闭包的应用场景
五:总结
<script type="text/javascript">
//理解闭包学会三个基本事实
// 一、JS 允许引用在当前函数以外定义的变量
function makeOffice(name) {
function make(age) {
return name + '----' + age;
}
return make(19);
}
var result = makeOffice("herry");
//二、即使外部函数已经返回,当前函数仍然可以引用在外部函数所定义的变量
function makeOffice2(name) {
function make(age) {
return name + '----' + age;
}
return make;
}
var f = makeOffice2('jack');
var result2 = f('20');//即使makeOffice2函数已经返回,make 函数仍能记住makeOffice2的值
//函数可以引用在其作用域范围内的任何变量 包括参数和外部函数的变量
function makeOffice3(name) {
return function (age) {
return name + '----' + age;
};
}
//三 闭包可以更新外部变量的值
//闭包存储的是外部变量的引用,而不是它们值得副本
function box() {
var val = undefined;
return {
set: function (newValue) {
val = newValue;
},
get: function () {
return val;
},
type: function () {
return typeof val;
}
};
}
</script>
浙公网安备 33010602011771号