javascript
深入理解JS中的变量作用域
在JS當中一個變量的作用域(scope)是程序中定義這個變量的區域。變量分為兩類:全局(global)的和局部的。其中全局變量的作用域是全局性的,即在JavaScript代碼中,它處處都有定義。而在函數之內聲明的變量,就只在函數體內部有定義。它們是局部變量,作用域是局部性的。函數的參數也是局部變量,它們只在函數體內部有定義。
我們可以借助JavaScript的作用域鏈(scope chain)更好地了解變量的作用域。每個JavaScript執行環境都有一個和它關聯在一起的作用域鏈。這個作用域鏈是一個對象列表或對象鏈。當JavaScript代碼需要查詢變量x的值時(這個過程叫做變量解析(variable name resolution)),它就開始查看該鏈的第一個對象。如果那個對象有一個名為x的屬性,那么就采用那個屬性的值。如果第一個對象沒有名為x的屬性,JavaScript就會繼續查詢鏈中的第二個對象。如果第二個對象仍然沒有名為x的屬性,那么就繼續查詢下一個對象,以此類推。如果查詢到最后(指頂層代碼中)不存在這個屬性,那么這個變量的值就是未定義的。
以上的過程并不是我們所熟悉的順序結構,但大致與順序結構類似只不過是將作用域當作一個整體來看待而已。整個過程如上圖所示
JS作用域實例
代碼一(平淡的不能再平淡的代碼)
[javascript]?view plaincopyprint?代碼二
[javascript]?view plaincopyprint?根據“多年”的編程經驗你可能覺得這兩個代碼輸出是一樣的,但是事實卻是第一個代碼正常輸出了變量的值----10,而第二個代碼輸出的卻是undefined。也許很多人理解不了,但是根據前面的作用域鏈的圖我們就很好理解了。
作用域鏈圖中很明確的表示出:在變量解析過程中首先查找局部的作用域,然后查找上層作用域。在代碼一的函數當中沒有定義變量i,于是查找上層作用域(全局作用域),進而進行輸出其值。但是在代碼二的函數內定義了變量i(無論是在alter之后還是之前定義變量,都認為在此作用域擁有變量i),于是不再向上層的作用域進行查找,直接輸出i。但是不幸的是此時的局部變量i并沒有賦值,所以輸出的是undefined。
《JavaScript權威指南》中提出的“沒有塊級作用域”實際上就是上述的意思。很多時候認為懂了、理解了,其實沒有懂,細細的研究一番之后看回過頭來再書中那加粗的文字,頓時恍然大悟,其實人家書里說的挺清楚的嘛!
總結
以上是生活随笔為你收集整理的深入理解JS中的变量作用域的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 实例讲解js中的预编译
- 下一篇: javascript深入理解js闭包