js詞法作用域
作用域
域,表示的是一個範圍,作用域,就是作用範圍。
作用域說明的是一個變量可以在什麽地方被使用,什麽地方不能被使用。
塊級作用域
JavaScript中沒有塊級作用域
{
var num = 123;
{
console.log( num );
}
}
console.log( num );
上面這段代碼在JavaScript中是不會報錯的,但是在其他的編程語言中(C#、C、JAVA)會報錯。
這是因為,在JavaScript中沒有塊級作用域,使用{}
標記出來的代碼塊中聲明的變量num
,是可以被{}
外面訪問到的。
但是在其他的編程語言中,有塊級作用域,那麽{}
num
,是不能在代碼塊外部訪問的,所以報錯。
詞法作用域
什麽是詞法作用域?
詞法( 代碼 )作用域, 就是代碼在編寫過程中體現出來的作用範圍. 代碼一旦寫好, 不用執行, 作用範圍就已經確定好了. 這個就是所謂詞法作用域.
在 js 中詞法作用域規則:
-
函數允許訪問函數外的數據.
-
整個代碼結構中只有函數可以限定作用域.
-
作用域規則首先使用提升規則分析
-
如果當前作用規則中有名字了, 就不考慮外面的名字
JavaScript 預解析
當變量和函數的聲明處在作用域比較靠後的位置的時候,變量和函數的聲明會被提升到作用域的開頭。
作用域鏈
什麽是作用域鏈
只有函數可以制造作用域結構, 那麽只要是代碼,就至少有一個作用域, 即全局作用域。
凡是代碼中有函數,那麽這個函數就構成另一個作用域。如果函數中還有函數,那麽在這個作用域中就又可以誕生一個作用域。
將這樣的所有的作用域列出來,可以有一個結構: 函數內指向函數外的鏈式結構。就稱作作用域鏈。
繪制作用域鏈的步驟:
-
看整個全局是一條鏈, 即頂級鏈, 記為 0 級鏈
-
看全局作用域中, 有什麽變量和函數聲明, 就以方格的形式繪制到 0 級練上
-
再找函數, 只有函數可以限制作用域, 因此從函數中引入新鏈, 標記為 1 級鏈
-
然後在每一個 1 級鏈中再次往復剛才的行為
變量的訪問規則
-
首先看變量在第幾條鏈上, 在該鏈上看是否有變量的定義與賦值, 如果有直接使用
-
如果沒有到上一級鏈上找( n - 1 級鏈 ), 如果有直接用, 停止繼續查找.
-
如果還沒有再次往上剛找... 直到全局鏈( 0 級 ), 還沒有就是 is not defined
-
註意,同級的鏈不可混合查找
聲明變量使用`var`, 如果不使用`var`聲明的變量就是全局變量( 禁用 )
js詞法作用域