2015-11-01 75 views
0

我有以下代碼:使用Javascript - 的函數的外部引用顯示「未定義」

function log(a) { 
    var b = 5; 
    a(); 

} 

log(function(){ 
    console.log(b); 
}); 

當功能日誌被執行的匿名功能,我得到「B沒有定義」。好吧,看起來anon的外部環境引用不是日誌的,因爲如果它不是在它內部創建的,所以它無法找到該變量。那麼它在哪裏被創建?在全球層面?我最初的想法是,這些圓括號使日誌內創建的匿名函數。

+2

JavaScript使用詞法作用域,因此它是定義函數的地方,用於決定您有權訪問哪些變量名稱。閱讀「詞彙範圍」與「動態範圍」。 – folkol

+0

那麼在這種情況下,它在哪裏坐着詞法呢? – RunningFromShia

+0

單從這段代碼我們無法判斷。但至少不是在「功能日誌」裏面。 – folkol

回答

0

在JavaScript範圍內存在函數。所以你的b變量只在其範圍內可見 - 匿名函數。如果你想讓它在函數外面可見,那麼你可以把變量賦值給全局範圍。

function log(a) { 
    window.b = 5; 
    a(); 
} 

log(function(){ 
    console.log(b); 
}); 
+0

請不要這樣做。只需使用一個函數參數並將其作爲參數傳遞。 – Bergi

+0

剛剛玩過他的代碼讓他明白。沒有人說這是一個完美的合法生產就緒代碼。 – Sagi

1

每次調用一個函數,假設你不聲明全局變量(你沒有聲明的),是這個函數創建的範圍和發生的事情在該範圍不是由地方確定功能是,稱爲,但是由定義爲。您可以看到,在定義匿名函數的位置(在調用日誌中),變量b不在該範圍內,因此它不可用。

讓我們重寫代碼:

function log(a) { 
    var b = 5; 
    a(); 
} 
function logger() { 
    console.log(b); 
} 
log(logger); 

你可以看到你的代碼和我都在做同樣的事情,唯一的區別是,我的代碼沒有一個匿名函數。他們不在他們的範圍內共享共同變量。

現在檢查了這一點:

var b = 5; 
function log(a) { 
    a(); 
} 
function logger() { 
    console.log(b); 
} 
log(logger); 

現在無論是日誌和記錄器份額在其範圍的一個共同的變量b(日誌不採用B,所以如果你在一個調試器將是不確定的檢查)。正如我所說,你不確定函數被調用的範圍,而是根據聲明的位置和方式確定範圍。

+0

謝謝,所以我們可以說anon函數位於全局級別,因爲它是在log函數最終執行之前創建的? – RunningFromShia

+0

@ user2081462:這個調用並不重要,但是當時的範圍是全球範圍。如果您沒有使用匿名函數,而是在'log(...)'之前聲明它,則可能更明顯 – Bergi

+0

user2081462。不,我沒有這樣說。兩種功能都處於同一水平。我更新了我的答案,所以我希望更清楚我想說什麼。 – sergeyz