JS作用域


什么是作用域?

這篇文章引用了《高性能JavaScript》這本書中一些作用域的知識,有興趣的朋友可以看一看。

既然是JS基礎類別的,自然就少不了JS作用域的知識。js中的作用域分為全局作用域和局部作用域。js中並沒有 像java語言中的塊級作用域。

全局作用域

var a = 0;

if (true) {
  var b = 1;
}

console.log(b); // 輸出1

像這樣在全局中定義a變量,為全局變量,在任何地方都能訪問到這個a變量。
因為js中沒有塊級作用域,所以在 if 或是 for 這樣邏輯語句中定義的變量都是可以被外界訪問到的。

局部作用域

局部作用域也可以稱之為函數作用域。

function fn () {
  var c = 2;
}

console.log(c); // 報錯,c變量未定義

局部作用域中定義的變量,只供局部作用域調用,外界無法訪問。

作用域鏈

Function對象有一個僅供 JavaScript 引擎存取的內部屬性。

這個屬性就是[[Scope]][[Scope]]包含了一個函數被創建的作用域中對象的集合。這個集合被稱為函數的作用域鏈,它決定了哪些數據能被函數訪問。

關於作用域鏈,局部作用域可以訪問到全局作用域中的變量和方法,而全局作用域不能訪問局部作用域的變量和方法。

var a = 0;

function fn () {
  var b = 1;
  console.log(a); // 輸出 1
}

// 全局作用域並不能訪問 fn 函數中定義的 b 變量
console.log(b); // 報錯

fn();

當函數fn()創建時,它的作用域中插入了一個對象變量,這個全局對象代表所有在全局范圍內定義的變量。

scope.png

當函數fn()執行時,會創建一個名為執行環境的獨一無二的內部對象。函數每執行一次,都會創建一個執行環境。當函數執行完畢,執行環境就會被銷毀。

每個執行環境都有自己的作用域鏈,用來解析標識符。當執行環境被創建時,它的作用域就會初始化為當前運行函數的[[Scope]]屬性中的對象。

執行環境創建完成之后,就會生成一個"活動對象",這個對象包含了當前函數的所有局部變量命名參數參數集合this。此對象會被推入作用域鏈的最前端。

當執行環境被銷毀后,"活動對象"也會隨之被銷毀。

如下圖所示:

activeScope.png

fn()時,會使用到a變量,這時候就會搜索執行環境的作用域鏈,找到就使用,找不到就會到作用域鏈的下一個對象找,如果搜尋到最后,還沒找到,那就認定這個變量是未定義的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM