乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      自由變量與閉包

       昵稱10087950 2022-06-16 發(fā)布于江蘇

      在講閉包之前,我們先了解一下什么是自由變量。

      自由變量是指在函數中使用的,但既不是函數參數也不是函數的局部變量的變量

      示例代碼:

      let a = 1;

      function foo() {
      console.log(a);
      }

      foo();

      上述代碼中,對于函數 foo 來說,a 既不是函數參數也不是函數的局部變量的變量,因此 a 屬于自由變量。

      什么是閉包

      在ECMAScript中,閉包(Closure)是指能夠訪問自由變量的函數。

      按照以上的概念,我們可以說所有函數都是閉包,因為它們都是在創(chuàng)建的時候就保存了上層上下文的作用域鏈,觀察如下代碼:

      let a = 1;

      function foo() {
      console.log(a);
      }

      foo(); // > 1

      (function () {

      let a = 2;
      foo(); // > 1

      })();

      ECMAScript 使用的是詞法作用域(Lexical scoping,又稱靜態(tài)作用域),即在函數創(chuàng)建時,就保存上層上下文的作用域鏈,上述代碼中,foo 函數創(chuàng)建時,其所使用的變量 a 是已經在上下文中靜態(tài)保存好的,因此在執(zhí)行 foo() 時 a 的值為 1。

      而任何函數,在其創(chuàng)建時保存的上層上下文的作用域中都有全局的自由變量 global(在瀏覽器中,global 為 window),因此說所有函數都是閉包。

      實踐中的閉包

      上面說的是理論上的閉包,但在實踐中,閉包不僅僅只是能夠訪問自由變量的函數,閉包是指引用了自由變量的,并且被引用的自由變量將和這個函數一同存在的函數,在創(chuàng)建該函數的上下文已經銷毀時,該函數仍然存在。

      示例代碼:

      function foo(){
      let a = 1;

      return function(){
      console.log(a)
      }
      }
      foo()

      上述代碼中,foo 函數執(zhí)行后返回了一個匿名函數,該函數引用了自由變量 a,而在 foo() 執(zhí)行完畢后,創(chuàng)建該函數的環(huán)境已經銷毀,但該函數并沒有被銷毀,因此 foo() 的返回值就是一個閉包。

      閉包會使引用的自由變量不能被清除,這就使得閉包比其他函數占用內存更多,但這也是閉包的強大之處,以下是一個使用閉包的例子:

      let foo = function() {

      let a = 1;

      return {
      add:function(){
      return ++a;
      },
      sub:function(){
      return --a;
      }
      }
      }

      let f = foo();
      f.add(); // 2
      f.sub(); // 1

      再來看一個面試中經常遇到的題目:

      let data = [];

      for (var i = 0; i < 3; i++) {
      data[i] = function () {
      console.log(i);
      };
      }

      data[0](); // 3
      data[1](); // 3
      data[2](); // 3

      這三個函數創(chuàng)建時均使用的是已經在上下文中靜態(tài)保存好的變量 i,而在 for 循環(huán)結束時,變量i 的值為3,當 data[0]() 執(zhí)行時,其所引用的自由變量 i 的值為 3,因此輸出3。

      我們的目標是輸出0、1、2,上面的例子顯然無法實現這個需求,利用閉包可以很輕松地解決這個問題:

      let data = [];

      for (var i = 0; i < 3; i++) {
      data[i] = (function(x) {
      return function () {
      alert(i);
      };
      })(i); // 傳入"i"值
      }

      data[0](); // 0
      data[1](); // 1
      data[2](); // 2

        本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現有害或侵權內容,請點擊一鍵舉報。
        轉藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多