zoukankan      html  css  js  c++  java
  • 对闭包最好的解释

    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代码,把size12size14size16分别绑定到不同的按钮上,就实现了点击相应的按钮,变成相应的字号。在这里,按钮是对象,按钮只有一个改变字号的方法,所以可以使用闭包。

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

     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后面的东西照抄就行,里面的已知变量记得换掉,就是这么简单。这种简单的可能无须这么做,但是遇到复杂的闭包的时候,这么做就非常有助于理解了。

  • 相关阅读:
    android studio学习---怎么创建一个新的module并且再次运行起来(在当前的project里面)
    你真的了解WebSocket吗?
    vue学习(十二)vue全家桶 Vue-router&Vuex
    GoJs的使用
    vue学习(十一)vue-cli3开发单文件组件
    vue学习(十)mixin 偷懒
    vue学习(九)对象变更检测注意事项
    vue学习(八)nextTick[异步更新队列]的使用和应用
    django的url 传不传参
    vue学习(七)refs的使用
  • 原文地址:https://www.cnblogs.com/antstory/p/6427173.html
Copyright © 2011-2022 走看看