对闭包最好的解释

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures

废话不多说,直接看例子:

 1 function makeFunc() {
 2   var name = "Mozilla";
 3   function displayName() {
 4     alert(name);
 5   }
 6   return displayName;
 7 }
 8 
 9 var myFunc = makeFunc();
10 myFunc();

这里的myFunc就是闭包,闭包本身也是个函数,它是嵌套在父函数里面被父函数返回的那个函数,它共享了父函数的环境,能获取父函数里定义的变量。在这里,父函数其实就变成了一个函数工厂,创建出来的函数赋给谁,谁就是闭包。

闭包有啥特点?按理makeFunc函数在执行完后(倒数第二条语句),里面的name变量应该就消失了,但是下一条myFunc()语句还是访问到name变量,这就是闭包的魔力。

这是因为闭包是由两部分组成的,函数,以及创建该函数的环境。

闭包可以用在什么地方?试着理解这句话:可以使用只有一个方法的对象的地方,都可以使用闭包。还是直接看例子:

1 function makeSizer(size) {
2   return function() {
3     document.body.style.fontSize = size + 'px';
4   };
5 }
6 
7 var size12 = makeSizer(12);
8 var size14 = makeSizer(14);
9 var size16 = makeSizer(16);

这是一个放大字号功能的JS代码,把size12\size14\size16分别绑定到不同的按钮上,就实现了点击相应的按钮,变成相应的字号。在这里,按钮是对象,按钮只有一个改变字号的方法,所以可以使用闭包。

再深化下,看一个更高级的例子:

 1 var Counter = (function() {
 2   var privateCounter = 0;
 3   function changeBy(val) {
 4     privateCounter += val;
 5   }
 6   return {
 7     increment: function() {
 8       changeBy(1);
 9     },
10     decrement: function() {
11       changeBy(-1);
12     },
13     value: function() {
14       return privateCounter;
15     }
16   }   
17 })();
18 
19 console.log(Counter.value()); /* logs 0 */
20 Counter.increment();
21 Counter.increment();
22 console.log(Counter.value()); /* logs 2 */
23 Counter.decrement();
24 console.log(Counter.value()); /* logs 1 */

这里有两点高级货要讲,一是使用了匿名函数自执行,即var Counter = (func(){})();这种情况下,其实就相当于把本文的第一个例子的前两条语句合并成了一条语句,此时Counter成了闭包。二是外围函数里返回的不是一个函数,而是好几个函数,这些方法共享同样的环境,但函数不一样,记住闭包的定义,闭包=函数+环境。

有一个技巧对于理解闭包很有作用,一定要讲下,举个例子:

 1 function makeAdder(x) {
 2   return function(y) {
 3     return x + y;
 4   };
 5 }
 6 
 7 var add5 = makeAdder(5);
 8 var add10 = makeAdder(10);
 9 
10 console.log(add5(2));  // 7
11 console.log(add10(2)); // 12

第7,8行的代码乍看之下非常费解,其实要理解很简单,只要把=号右边改写下,写成

var add5 = function(y){
  return 5 + y;  
}

写成这种形式后,对于为什么add5(2)是7就一目了然了?那么怎么就确定要这么写呢?很简单,你把return后面的东西照抄就行,里面的已知变量记得换掉,就是这么简单。这种简单的可能无须这么做,但是遇到复杂的闭包的时候,这么做就非常有助于理解了。

posted @ 2017-02-22 01:48  蚂蚁不排队  阅读(193)  评论(0编辑  收藏  举报