2016-07-23 77 views
1

在下面的代碼:Javascript:爲什麼具有全局執行上下文的回調函數可以訪問範圍變量?

function test() { 
    var x = 5 // scoped to test function 
    console.log(this); // global object 
    logCb(function(){ 
     console.log(this); // global object 
     console.log(x); 
    }) 
} 

function logCb (cb) { 
    console.log(this); // global object 
    cb() // This still seems to execute within the test function scope? why... 
} 

test() 

x被作用域進行測試,這是回調函數被定義在哪裏。因爲logCb()函數不能訪問x變量,所以我會預計行cb()會拋出一個錯誤。

但事實並非如此。爲什麼?看起來回調函數中的引用是在賦值過程中創建的,而不是在執行過程中創建的 - 如果您考慮提升 - 即在編譯過程中,回調函數被提升到「test」的頂部,然後賦值在測試中發生範圍?

我已經讀過,執行與作用域不一樣。在本文中:http://ryanmorr.com/understanding-scope-and-context-in-javascript/,這句話scope pertains to the variable access of a function when it is invoked and is unique to each invocation似乎暗示回調是從測試函數中調用的。

因爲在我看來,不管在哪裏調用回調函數,它仍然會被測試範圍。

我想我的問題是:

如何在回調函數中定義的條款來處理,然後考慮範圍和執行上下文時調用?

+0

你有沒有聽說過在JavaScript關閉? –

+0

函數的作用域是基於它聲明的地方,而不是從那裏調用的地方。函數的'this'與範圍無關,並且基於* how *函數被調用。 – nnnnnn

+0

@RajaprabhuAravindasamy。所以回調已經結束了測試? –

回答

1

在思考範圍和執行上下文時,如何根據定義處理回調函數,然後調用 ?

一個功能範圍是基於它是在詞法環境實際存在

說明:回調功能測試()詞彙存在,所以它總是試圖找到內本身的任一值(如果存在的話),否則它會看到其在外部環境

值(其爲功能測試在這種情況下) 測試功能LogCb功能將遵循相同的做法。在這種情況下,外部環境將全球

如何發動機跟蹤範圍分頭執行 背景?

詞法環境:東西在哪裏坐在身在你寫的代碼。

執行上下文:包裝幫助管理正在運行的代碼。

現在在你的代碼中有很多詞法環境。哪一個當前正在運行通過執行上下文進行管理。它可以包含超出您在代碼中編寫的內容的內容。

每當執行上下文被創建,我們有三樣東西是提供給我們:

  1. 全局對象(窗口):在全球範圍內的任何變量或函數被鏈接到窗口對象
  2. 「這個」
  3. 外環境

所以取決於哪個執行上下文當前正在運行,這些東西會按照它在哪裏物理或詞法存在於代碼變化。例如,對於cb外環境是function test()

+0

引擎如何跟蹤範圍與執行上下文分開? –

1

範圍由其中一個功能是創建,而不是由其中它被稱爲確定。

您傳遞給logCb的功能是在test內部創建的,所以它可以訪問test的範圍。

+0

您是否知道解釋Google V8引擎如何執行此操作的好方法? –

1

當在javascript中調用某個函數時,會將一個上下文傳遞給它。

上下文可使用新是通過以下方式

  1. 一個,創建一個臨時對象,並將其作爲上下文傳遞給函數

  2. 經由對象a.getValue調用函數( )。的getValue獲取上下文

  3. 如果沒有上述2通過全局對象,即窗口