簡體   English   中英

閉包和ES2015

[英]Closures and ES2015

我提前為另一個封閉問題道歉,但我想澄清一下我對JavaScript中實現閉包的方式的理解。

請考慮以下代碼:

01 'use strict';
02 function foo() {}
03 foo();

我在今年早些時候在一個問題中建立了一個閉包在概念上(如果不是實際上由於引擎優化)在這里創建的。

並且在第3行調用foo之前,不會創建相應的執行上下文。

因此,據我所知,在評估此代碼時:

  1. 每個執行上下文都有一個“LexicalEnvironment”組件,用於解析其中的代碼所引用的標識符引用(8.3,表23)。
  2. 調用FunctionCreate ,將引用(名為“scope”)傳遞給當前執行上下文的“LexicalEnvironment”組件。 (19年1月14日)
  3. FunctionCreate調用FunctionInitialize傳遞“scope”(9.2.5)
  4. FunctionInitialize確保正在創建的函數對象的[[Environment]]內部插槽設置為“scope”的值(對當前執行上下文的“LexicalEnvironment”組件的引用)(9.2.4)

最后,當實際調用foo時,我發現規范難以解釋。

  1. PrepareForOrdinaryCall ,調用的新執行上下文的“LexicalEnvironment”被設置為調用NewFunctionEnvironment (9.2.1.1)的結果
  2. NewFunctionEnvironment將對外部執行上下文(函數對象的[[Environment]]槽的“LexicalEnvironment”組件的引用復制到正在構建的執行上下文的“LexicalEnvironment”組件的Environment記錄( EnvironmentRecord ?)中“外部詞匯環境參考”(8.1.2.4)

因此,閉包以兩步方式實現:

  1. 在函數對象實例化時創建函數對象與封閉執行上下文的封閉“LexicalEnvironment”之間的鏈接。 這是函數對象的[[Environment]]內部插槽。
  2. 調用函數時,對外部執行上下文的封閉“LexicalEnvironment”組件( 函數對象[[Environment]]槽的內容)的引用被復制到spec-imprecisely-defined(?)/ EnvironmentRecord (?)新執行上下文的“LexicalEnvironment”組件的子組件。

聽起來不錯嗎?

聽起來不錯嗎?

差不多。 我只是不會使用“復制”的工作,而是“鏈接”。 為了簡化它:

  1. 創建函數時,它存儲引用它創建它的環境。
  2. 當執行該功能時,該存儲的環境成為新創建的功能環境的“外部環境”。

或者在圖片中:

                  +----------------+                     +----------------+
   Function       |                |   [[Environment]]   |     Outer      |
   creation       |    Function    |-------------------->|  Environment   |
                  |                |                     |                |
                  +----------------+                     +----------------+
                                                                  ^        
                                                                  |        
                                                                  |        
                  +----------------+                              |        
   Function       |    Function    |  outer environment reference |        
   execution      |  Environment   |------------------------------+        
                  |                |                                       
                  +----------------+                                       

每個函數都會發生這種情況,並且根據您對閉包1的定義,這會使每個函數成為閉包(或不閉包)。


1:我相信有兩個關於函數成為閉包的意義:

  • 如果函數存儲對它所創建的環境的引用,那么它是一個閉包(適用於JS中的每個函數)
  • 如果函數存儲對它所創建的環境的引用 “離開”該環境(環境“不再存在”),那么它就是一個閉包。 當然並非總是如此。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM