詞法作用域
阿新 • • 發佈:2017-08-07
... 比較 定義 聲明 如果 define 原型 nbsp java
作用域
域表示的就是 範圍, 即 作用範圍. 就是一個名字在什麽地方可以被使用, 什麽時候不能使用.
塊級作用域
即塊級別的作用範圍
// 在 C , Java 等編程語言中, 下面的語法報錯 { var num = 123; // int { console.log( num ); // => 123 } } console.log( num ); // 報錯
在 js 中采用詞法作用域
所謂的 詞法( 代碼 )作用域, 就是代碼在編寫過程中體現出來的作用範圍. 代碼一旦寫好, 不用執行,
作用範圍就已經確定好了. 這個就是所謂詞法作用域.
在 js 中詞法作用域規則:
- 函數允許訪問函數外的數據.
- 整個代碼結構中只有函數可以限定作用域.
- 作用規則首先使用提升規則分析
- 如果當前作用規則中有名字了, 就不考慮外面的名字
作用域鏈
可以發現只有函數可以制造作用域結構. 那麽只要是代碼, 至少有一個作用域, 即全局作用域.
凡是代碼中有函數, 那麽這個函數就構成另一個作用域. 如果函數中還有函數, 那麽再這個作用域中就
又可以誕生一個作用域. 那麽將這樣的所有的作用域列出來, 可以有一個結構: 函數內指向函數外的鏈式結構.
繪制作用域鏈的步驟:
- 看整個全局是一條鏈, 即頂級鏈, 記為 0 級鏈
- 看全局作用域中, 有什麽成員聲明, 就以方格的形式繪制到 0 級練上
- 再找函數, 只有函數可以限制作用域, 因此從函數中引入新鏈, 標記為 1 級鏈
- 然後在每一個 1 級鏈中再次往復剛才的行為
變量的訪問規則
- 首先看變量在第幾條鏈上, 在該鏈上看是否有變量的定義與賦值, 如果有直接使用
- 如果沒有到上一級鏈上找( n - 1 級鏈 ), 如果有直接用, 停止繼續查找.
- 如果還沒有再次往上剛找... 直到全局鏈( 0 級 ), 還沒有就是 is not defined
- 註意, 切記 同級的鏈不可混合查找
如何分析代碼
- 在分析代碼的時候切記從代碼的運行進度上來分析, 如果代碼給變量賦值了, 一定要標記到圖中
- 如果代碼比較復雜, 可以在圖中描述代碼的內容, 有事甚至需要將原型圖與作用域圖合並分析
var num = 123; function f1() { console.log( num ); } function f2() { var num = 456; f1(); } f2();
補充
- 聲明變量使用 var, 如果不使用 var 聲明的變量就是全局變量( 禁用 )
- 因為在任何代碼結構中都可以使用該語法. 那麽在代碼維護的時候會有問題. 所以除非特殊原因不要這麽用.
-
下面的代碼的錯誤
function foo () { var i1 = 1 // 局部 i2 = 2, // 全局 i3 = 3; // 全局 }
4.此時註意
var arr = []; for ( var i = 0; i < 10; i++ ) { arr.push( i ); } for ( var i = 0; i < 10; i++ ) { console.log( arr[ i ] ); } // 一般都是將變量的聲明全部放到開始的位置, 避免出現因為提升而造成的錯誤 var arr = [], i = 0; for ( i=0; i < 10; i++ ) { arr.push( i ); } for ( i = 0; i < 10; i++ ) { console.log( arr[ i ] ); }
詞法作用域