一:什么是闭包
《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>