簡體   English   中英

JavaScript函數作用域屬性-在閉包的哪一點設置?

[英]JavaScript function scope property - at what point in a closure is it set?

以下函數返回一個對象。 它取自MDN文檔。 返回的對象具有作為函數的屬性,這些屬性引用“私有”函數changeBy()。

我很確定,增量()調用將解決changeBy()函數調用的唯一方法是可以訪問作用域鏈-封閉/父函數的作用域。

問:作用域鏈屬性是否在聲明了它的增量()函數上設置,即使它是在對象內部聲明的,並且此時尚未被調用?

注意:我正在指出JavaScript閉包如何工作? 作為可能的重復項。

神奇的是,在JavaScript中,函數引用還具有對其創建所在的閉包的秘密引用-類似於委托是方法指針又是對對象的秘密引用

問: 秘密是我要問的問題,那里給出的答案中沒有解釋。 此引用存儲在哪里?

var makeCounter = function() {
  var privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }
  return {
    increment: function() {
      changeBy(1);
    },
    value: function() {
      return privateCounter;
    }
  }  
};

var counter1 = makeCounter();
alert(counter1.value()); /* Alerts 0 */
counter1.increment();
alert(counter1.value()); /* Alerts 1 */

范圍鏈屬性是否在聲明了它的increment()函數上設置,即使它是在對象內部聲明的,並且此時尚未被調用?

是。

increment與它所處的詞法環境相關聯,並且即使通過返回而被“釋放到野外”(無論是直接返回還是作為您正在做的事情)作為in的值,也可以訪問該環境中的所有變量。返回的對象。

秘密是我要問的,那里沒有給出答案。 此引用存儲在哪里?

它寫在粘貼在冰箱門上的便利貼上。 不,嚴重的是,在解析和解釋JS時,它作為內部數據結構的一部分存儲在引擎內部。

順便說一句,您正在濫用術語“關閉”。 “關閉”不僅僅意味着“功能”,匿名或其他方式。 它指的是外部范圍內的變量(“封閉”)與該范圍內定義的引用它們的函數(“封閉范圍”)之間的特定交互作用和行為。

我找到了我在ECMAScript規范中所需的詳細程度的答案。 這非常深入,但是它解釋了函數創建/初始化過程以及在對象文字中創建函數時的初始化過程。

ECMAScript 5.1規范

正在創建功能

創建函數(而不是調用函數)時,步驟9覆蓋了scope屬性:其中[[Scope]]指定詞法環境,並且F是新函數,而Scope是當前函數的作用域/詞法環境:

9:將F的[[Scope]]內部屬性設置為Scope的值

輸入功能代碼 10.4.3

  1. 令localEnv為調用NewDeclarativeEnvironment的結果,並傳遞F的[[Scope]]內部屬性的值作為參數。
  2. 將LexicalEnvironment設置為localEnv。

對象文字 11.1.5中 創建的函數

我感興趣的部分是“將正在運行的執行上下文的LexicalEnvironment作為范圍傳遞”

  1. 令閉包為創建13.2中指定的具有空參數列表和FunctionBody指定的主體的新Function對象的結果。 傳遞正在運行的執行上下文的LexicalEnvironment作為范圍。 如果PropertyAssignment包含在嚴格代碼中,或者其FunctionBody是嚴格代碼,則將Strict標志作為true傳遞。

ECMAScript 2016

將F的[[Environment]]內部插槽設置為Scope的值。

暫無
暫無

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

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