关于javascript:谈谈什么是闭包

5次阅读

共计 1259 个字符,预计需要花费 4 分钟才能阅读完成。

前言

说到闭包真的是让我头大的货色,始终以来都只是一个概念,平时也简直不必,所以始终都没太搞懂。都是最近在看防抖,节流函数的写法,举荐应用闭包来写,所以才从新来了解闭包,防抖和节流之后也会独自写一篇文章来论述吧。

什么是闭包

MDN 中对闭包的定义如下:

函数和对其四周状态(lexical environment,词法环境)的援用捆绑在一起形成闭包(closure)

上述句子换句话说就是:闭包是由函数及其援用的变量形成的。那么就有一个问题了,那岂不是所有函数只有外部援用内部的变量都能形成一个闭包,例如:

    let a = 1;
    function printA(){console.log(a);
    }

依照定义的确上述例子也形成闭包,但怎么跟咱们平时见到的闭包不一样呢?

《JavaScript 权威指南中》的确也写道:

从技术角度讲,所有的 JavaScript 都是闭包。

但从理论利用思考,这样的闭包就没有存在的意义,所以 MDN 补充道:

也就是说,闭包能够让你从外部函数拜访内部函数作用域。

<p style=”color: red”> 所以援用的变量应该为函数作用域内的变量,换句话说,闭包应存在于函数作用域外部,例如:</p>

    // a 与 printA 形成一个闭包
    function func(){
      let a = 1;
      function printA(){console.log(a);
      }
      printA();}
    func();

看到这个例子有人可能会想,怎么我看到的闭包都会 return 一个函数呀?实际上是一样的,return 进来只是为了内部调用而已,实质上一样的嘛。

对于为什么可能在外部函数中援用内部函数的变量,对作用域稍有理解的人就会晓得:函数中援用变量时,会先从本身函数中读取,如果外部没有就逐层往上读取,直至读取到。这里特地提一点,函数依赖于变量作用域,这个作用域是在函数定义是决定的,而不是函数调用时决定的。( 起源《JavaScript 权威指南》)所以寻找变量时应该从定义时的函数中往上寻找,而非调用时,举个例子:

    function func(){
      let a = 1;
      console.log(a);
    }
    let a = 2;
    func();  //1

闭包的简略利用

后面说了那么多,那么闭包到底有什么用?闭包的常见用法就是提供间接拜访一个变量的办法,有时候咱们须要在某些中央用到一个变量,然而又不能定义为全局变量,存在着篡改的危险,那么咱们就能够用定义位公有变量,而后通过闭包裸露进来,例如通过闭包写一个计数器,代码如下:

    function count(){
        let num = 0;
            return {add: function () {
                    num++;
                    return num;
                },
                sub: function () {
                    num--;
                    return num;
                },
                reset: function () {
                    num = 0;
                    return num;
                }
            }
        }
        let counter = count();
        counter.add();  //1
        counter.add();  //2
        counter.sub();  //1
        counter.reset(); //0
        counter.add();  //1
正文完
 0