關于閉包的理解

1.對于閉包,個人理解:

有權訪問另一個函數作用域中的變量的函數

示例:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>

<body>
  <script>
    var outerValue = '我是外部變量';
    var later;
    function outerFunction() {
      var innerValue = '我是內部變量';
      var innerFunction = function () {
        console.log(outerValue);
        console.log(innerValue);
      };
      later = innerFunction;
    }
    outerFunction();
    later();
  </script>
</body>

</html>

打印結果

閉包是一種特殊的對象。
它由兩部分構成:函數,以及創建該函數的環境。環境由閉包創建時在作用域中的任何局部變量組成。

理解閉包的關鍵在于:外部函數調用之后其變量對象本應該被銷毀,但閉包的存在使我們仍然可以訪問外部函數的變量對象,這就是閉包的重要概念。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <script>
    let outer;
    function father(){
      let inner = '我是函數的內部變量';
      function child(){
        console.log(inner);
      }
    }
    father();
  </script>
</body>
</html>
打印結果,并沒有打印出inner

分析:此時js腳本中,調用了father函數,該函數含有一個內部變量inner,同時在該函數中創建了另一個child函數,child函數可以訪問father函數的內部變量,但是child函數在father函數的內部,外部沒法直接調用,所以控制臺沒有打印任何結果

換一下寫法:

<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <script>
    let outer;
    function father(){
      let inner = '我是father函數的內部變量';
      outer = function child(){
        console.log(inner);
      }
    }
    father();
    outer();
  </script>
</body>
</html>
有打印結果

此時有打印結果,因為child函數的引用賦給了一個外部的變量

產生一個閉包
? ?創建閉包最常見方式,就是在一個函數內部創建另一個函數。下面例子中的 child 就是一個閉包:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <script>
    function father(){
      let a =1 ,b=2;
      function child(){ //閉包函數,訪問外部函數的
        return a+b; //返回father函數內部變量a+b的合
      }
      return child; //返回閉包函數
    }
    console.log(father());
  </script>
</body>
</html>
打印出閉包函數
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <script>
    function father(){
      let a =1 ,b=2;
      function child(){ //閉包函數,訪問外部函數的
        return a+b; //返回father函數內部變量a+b的合
      }
      return child(); //返回閉包函數的執行結果
    }
    console.log(father());
  </script>
</body>
</html>
打印出閉包函數的執行結果

閉包的作用域鏈包含著它自己的作用域,以及包含它的函數的作用域和全局作用域。

閉包的注意事項

.通常,函數的作用域及其所有變量都會在函數執行結束后被銷毀。但是,在創建了一個閉包以后,這個函數的作用域就會一直保存到閉包不存在為止。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容