[英]JavaScript scope in a try block
假設我正在嘗試執行此 JavaScript 代碼段。 假設未聲明的變量和方法在上面的其他地方聲明,並且something
和somethingElse
評估為 boolean-true。
try {
if(something) {
var magicVar = -1;
}
if(somethingElse) {
magicFunction(magicVar);
}
} catch(e) {
doSomethingWithError(e);
}
我的問題是: magicVar
的范圍是什么,可以像我一樣將它傳遞給magicFunction
嗎?
關於 Javascript 如何使用var
處理這個問題的許多其他很好的答案,但我想我會解決let
情況......
如果在try
塊內使用let
定義了一個變量,則它不會在catch
(或finally
)塊內的范圍內。 它需要在封閉塊中定義。
例如,在以下代碼塊中,控制台輸出將是“Outside”:
let xyz = "Outside";
try {
let xyz = "Inside";
throw new Error("Blah");
} catch (err) {
console.log(xyz);
}
Javascript 有函數作用域。 這意味着, magicvar
將從它聲明的函數的開始magicvar
存在到該函數的結尾,即使該語句從未執行過。 這稱為變量提升。 函數聲明也會發生同樣的事情,這又被稱為函數提升。
如果變量是在全局范圍內聲明的,它對所有內容都是可見的。 這是全局變量在 Javascript 中被認為是邪惡的部分原因。
如果something
為假,您的示例會將undefined
傳遞給magicFunction
,因為尚未將magicVar
分配給任何內容。
雖然這在技術上是有效的 Javascript,但它通常被認為是糟糕的風格,不會通過像 jsLint 這樣的樣式檢查器。 像這樣非常不直觀的 Javascript 將執行而不會出現任何錯誤
alert(a); //alerts "undefined"
var a;
POP QUIZ :下面的代碼有什么作用?
(function() {
x = 2;
var x;
alert(x);
})();
alert(x);
無功
您可能想閱讀MDN 范圍備忘單
由於hoisting
你甚至可以做這樣的事情:
function bar() {
var x = "outer";
function foo() {
alert(x); // {undefined} Doesn't refer to the outerscope x
// Due the the var hoising next:
x = 'inner';
var x;
alert(x); // inner
}
foo();
}
bar();
bar();
所以foo
函數被轉換成這樣:
function foo() {
var x;
alert(x); // {undefined} Doesn't refer to the outerscope x
// Due the the var hoising next:
x = 'inner';
alert(x); // inner
}
我的問題是:magicVar 的范圍是什么,可以像我一樣將它傳遞給 magicFunction 嗎?
定義好的...,是的,代碼是有效的,但是如果變量聲明在頂部,那么它的可讀性就會降低,僅此而已。
由於javascript“提升”(google it),您的變量聲明代碼被翻譯為:
function yourFunction() {
var magicVar;
try {
if(something) {
magicVar = -1;
}
if(somethingElse) {
magicFunction(magicVar);
}
} catch(e) {
doSomethingWithError(e);
}
} //end of your function
“提升”將所有變量聲明移動到函數的頂部。 因此, magicVar
在函數中的任何地方都可用,但在給它一個值之前它是未定義的。
您的變量具有函數作用域。
使用var
,變量從函數的開頭到函數的結尾都存在,無論它們在哪里聲明,或者即使語句實際上已經到達。 但是,在為它們分配另一個值之前,它們將是undefined
。
因此,在您的情況下,如果something
為假但somethingelse
為真,您將調用magicFunction
,其第一個參數為undefined
。
該let
關鍵字,在Javascript 1.9創建和提供(截至今日,5月3日2012,而據我所知)只在Firefox中,聲明了你可能使用的范圍的語義變量。
我同意變量提升和函數提升,我想強調兩個重點。
Catch 參數中定義的標識符是 ie err/e(error) ,作用域為 Catch 定義的塊。
功能第一吊裝。 例子 :
b(); // output : 3 var b = 2; function b(){ return 3; }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.