1. 程式人生 > >Javascript高階程式設計學習筆記(10)—— 作用域、作用域鏈

Javascript高階程式設計學習筆記(10)—— 作用域、作用域鏈

昨天介紹了,JS中函式的作用域

什麼詞法環境之類的,可能很多小夥伴不太明白。

在今天的內容開始之前,先做個簡短的宣告:

 

詞法環境這一概念是在ES5中提出的,因為詞法環境主要用於儲存let、const宣告的變數、函式

而在ES3中對變數相關的資訊都儲存在變數物件上;

從功能上來說變數物件可以看作是詞法環境中的環境記錄

兩者從功能上來說區別不大,只是不同版本的ES有不同的說法

 

為了保持與前文的一致,這篇文章中我還是用環境記錄來描述JS儲存當前執行環境(上下文)中定義的變數和函式的物件

ES6之前JS中的作用域只有全域性作用域和區域性作用域(函式作用域)兩種,後文將基於此進行解釋

作用域

作用域聯絡前文我們可以理解為執行環境(上下文)中的詞法環境

而每個作用域都由一個儲存變數的物件(環境記錄)和一個指向外部詞法環境的outer(對外部環境引用)構成

作用域之間的巢狀關係由outer來維護

一個個作用域通過outer形成的鏈式結構就被稱作作用域鏈

在《js高階程式設計》中把執行棧頂端的執行環境(上下文)中的作用域(詞法環境)稱為活動物件

 

作用域鏈

那麼作用域鏈是幹嘛的呢?

作用域鏈就是讓我們能在子作用域中訪問父作用域鏈中的變數的

在解釋作用域的時候我提過,每個作用域都包含了一個對外部作用域的引用,這個引用是單向的

這也是子作用域能訪問父作用域,而父作用域不能訪問子作用域的原因

 

 

當我們在使用變數的時候,JS會解析識別符號,解析實際上就是一個沿著作用域鏈一層層搜尋識別符號的過程

在搜尋識別符號這一過程中,只要搜尋到符合的識別符號就會立即停止搜尋

這也就是當父級作用域和子作用域有同名變數時,JS以子作用域中的為準的原因

 

 

延長作用域鏈

在JS中除了函式之外,還有一些語句也會產生作用域,從而延長作用域

1.try-catch中的catch會產生一個新的作用域

2.with語句 會將指定物件作為作用域新增到執行棧的頂端

 

在使用上方的語句時需要注意一下

PS . IE8 之前的JS版本中catch會將錯誤物件新增到當前的執行環境的變數物件中,而不是新建一個,IE9中修復了該bug

 

沒有塊級作用域

在ES6之前JS是沒有塊級作用域的,也就是大括號之間的程式碼塊不會產生一個獨立的作用域

也就是說花括號中間宣告的變數會新增到當前的執行環境中

這也是for迴圈中宣告的 i 在外部也能訪問的原因

 

最近的文章可能都沒有什麼例子的配合了,一是有些東西實在不好舉例,二是自己水平有限

望諒解,JS中的閉包等問題會在後面介紹object裡面的function型別的時候介紹