[英]Not able to understand the output of this javascript code
為什么以下代碼undefined
打印? 同樣,在刪除了if
塊之后,它會在此輸出hello there
。
var message = "hello there!";
function hello(){
console.log(message);
if (true) {
var message = "wassup?!";
}
}
hello();
這稱為吊裝 。 從Mozilla文檔 (添加了重點):
無論變量聲明在何處出現 ,都將在執行任何代碼之前對其進行處理。 用
var
聲明的變量的范圍是其當前的執行上下文 ,它是封閉的函數,或者對於在任何函數之外聲明的變量,是全局的。
在if
塊中聲明的var message
隱藏了函數內部所有代碼的全局message
變量,包括對console.log()
的調用。
還有兩個要點。 首先,JavaScript將變量聲明與變量初始化分開。 這就是為什么在執行console.log(message)
時,本地message
變量具有未定義值的原因,而不是"wassup?!"
。 其次,由於提升是一種違反直覺的行為(至少對於習慣於其他語言的程序員而言),因此大多數JavaScript整理工具都會警告您有關不在執行上下文開頭的var
語句。 我強烈建議您找到一個整理工具(想到的是JSLint,JSHint,ESLint和JSCS)並使用它。
當您定義與全局名稱相同的局部變量時,就會發生這種情況。 由於在函數范圍內有一個var message
,因此它將僅引用本地message
而不是全局message
。 由於當時未提供值,因此undefined
。 如果您以后將它移動到注意if
這將是"wassup?!"
。
解決的辦法是您可能不想創建局部變量。 因此更改var message = "wassup?!"
message = "wassup?!"
。
要添加到@Spencer Wieczorek的答案中,變量定義被“提升”到其作用域的頂部,而變量賦值仍保留在您編寫它的位置。 因此,您提供的代碼實際上是這樣翻譯的:
var message = "hello there!";
function hello(){
var message;
console.log(message);
if (true) {
message = "wassup?!";
}
}
hello();
這就更清楚地解釋了為什么您看到這些結果-在console.log()
調用之前, message
變量是在hello()
函數的作用域中創建的,但是沒有得到值'wassup?!'
直到函數中的更高版本。
編輯: 這是有關此行為的更多信息 ,正如@TedHopps在評論中指出的那樣,稱為“懸掛”,而不是“搭便車”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.