簡體   English   中英

try 塊中的 JavaScript 作用域

[英]JavaScript scope in a try block

假設我正在嘗試執行此 JavaScript 代碼段。 假設未聲明的變量和方法在上面的其他地方聲明,並且somethingsomethingElse評估為 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);
  • 在 javascript 中,只有函數創建一個新的上下文閉包。
  • 變量的每個定義實際上都是在其作用域頂部的變量聲明和在定義所在位置的賦值。

無功

  • 函數作用域
  • 提升到其功能的頂部
  • 在同一范圍內重新聲明同名是無操作的

您可能想閱讀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月32012,而據我所知)只在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.

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