功能範圍

定義函式時,它會建立一個範圍

函式外部的程式碼無法訪問函式中定義的所有內容。只有此範圍內的程式碼才能看到範圍內定義的實體。

function foo() {
  var a = 'hello';
  console.log(a);  // => 'hello'
}

console.log(a);  // reference error

巢狀函式在 JavaScript 中是可能的,並且適用相同的規則。

function foo() {
  var a = 'hello';
  
  function bar() {
    var b = 'world';
    console.log(a);  // => 'hello'
    console.log(b);  // => 'world'
  }

  console.log(a);  // => 'hello'
  console.log(b);  // reference error
}

console.log(a);  // reference error
console.log(b);  // reference error

當 JavaScript 嘗試解析引用或變數時,它會在當前範圍內開始查詢它。如果它在當前範圍內找不到該宣告,則會爬上一個範圍來查詢它。重複此過程直到找到宣告。如果 JavaScript 解析器到達全域性範圍但仍無法找到引用,則將引發引用錯誤。

var a = 'hello';

function foo() {
  var b = 'world';

  function bar() {
    var c = '!!';

    console.log(a);  // => 'hello'
    console.log(b);  // => 'world'
    console.log(c);  // => '!!'
    console.log(d);  // reference error
  }
}

這種攀爬行為也可能意味著一個參考可能會覆蓋外部範圍中類似命名的參考,因為它首先被看到。

var a = 'hello';

function foo() {
  var a = 'world';

  function bar() {
    console.log(a);  // => 'world'
  }
}

Version >= 6

JavaScript 解析範圍的方式也適用於 const 關鍵字。使用 const 關鍵字宣告變數意味著不允許重新分配值,但在函式中宣告它將建立一個新範圍並使用新變數。

function foo() {
  const a = true;

  function bar() {
    const a = false;  // different variable
    console.log(a);   // false
  }

  const a = false;    // SyntaxError
  a = false;          // TypeError
  console.log(a);     // true
}

但是,函式不是建立範圍的唯一塊(如果使用 letconst)。letconst 宣告具有最近的塊語句的範圍。有關詳細說明,請參見此處