JavaScript 系列之做用域(二)

這是我參與8月更文挑戰的第6天,活動詳情查看:8月更文挑戰markdown

3、詞法做用域和動態做用域

  • 詞法做用域:函數的做用域在函數定義的時候就決定了
  • 動態做用域:函數的做用域在函數調用的時候才決定的

看以下例子:app

let a = 2;
function foo() {
  console.log(a); // 會輸出2仍是3?
}
function bar() {
  let a = 3;
  foo();
}
bar()
複製代碼

假設 JavaScript 採用詞法做用域(也可稱爲靜態做用域),讓咱們分析下執行過程:ide

執行 foo 函數,先從 foo 函數內部查找是否有局部變量 a,若是沒有,就根據書寫的位置,查找上面一層的代碼,也就是 a 等於 2,因此結果會打印 2。函數

假設 JavaScript 採用動態做用域,讓咱們分析下執行過程:post

執行 foo 函數,依然是從 foo 函數內部查找是否有局部變量 a。若是沒有,就從調用函數的做用域,也就是 bar 函數內部查找 a 變量,因此結果會打印 3。ui

前面咱們已經說了,JavaScript 採用的是詞法做用域,因此這個例子的結果是 2。this

詞法做用域是寫代碼的時候就靜態肯定下來的;而動態做用域並不關心函數和做用域是如何聲明以及在何處聲明的,只關心它們從何處調用。換句話說,做用域鏈是基於調用棧的,而不是代碼中的做用域嵌套。lua

Javascript 並不具備動態做用域,它只有詞法做用域,簡單明瞭。可是,它的 eval()、with、this 機制某種程度上很像動態做用域,使用上要特別注意。url

詞法做用域是在寫代碼或者定義時肯定的,而動態做用域是在運行時肯定的(this也是!)。詞法做用域關注函數在何處聲明,而動態做用域關注函數從何處調用。spa

  1. this 相似動態做用域
  2. JavaScript 執行是靜態做用域
相關文章
相關標籤/搜索