Js做用域與做用域鏈詳解javascript
http://blog.csdn.net/yueguanghaidao/article/details/9568071java
一:函數做用域閉包
第一句輸出的是: "undefined",而不是 "global"函數
第二講輸出的是:"local".net
你可能會認爲第一句會輸出:"global",由於代碼還沒執行var scope="local",因此確定會輸出「global"。3d
我說這想法徹底沒錯,只不過用錯了對象。咱們首先要區分Javascript的函數做用域與咱們熟知的C/C++等的塊級做用域。對象
在C/C++中,花括號內中的每一段代碼都具備各自的做用域,並且變量在聲明它們的代碼段以外是不可見的。而Javascript壓根沒有塊級做用域,而是函數做用域.blog
所謂函數做用域就是說:-變量在聲明它們的函數體以及這個函數體嵌套的任意函數體內都是有定義的。事件
因此根據函數做用域的意思,能夠將上述代碼重寫以下:ip
咱們能夠看到,因爲函數做用域的特性,局部變量在整個函數體始終是由定義的,咱們能夠將變量聲明」提早「到函數體頂部,同時變量初始化還在原來位置。
爲何說Js沒有塊級做用域呢,有如下代碼爲證:
都輸出是「local",若是有塊級做用域,明顯if語句將建立局部變量name,並不會修改全局name,但是沒有這樣,因此Js沒有塊級做用域。
如今很好理解爲何會得出那樣的結果了。scope聲明覆蓋了全局的scope,可是尚未賦值,因此輸出:」undefined「。
因此下面的代碼也就很好理解了。
二:變量做用域
Js中沒有用var聲明的變量都是全局變量
三:做用域鏈
當執行s時,將建立函數s的執行環境(調用對象),並將該對象置於鏈表開頭,而後將函數t的調用對象連接在以後,最後是全局對象。而後從鏈表開頭尋找變量name,很明顯
name是"slwy"。
但執行ss()時,做用域鏈是: ss()->t()->window,因此name是」tlwy"
當文檔加載完畢,給幾個按鈕註冊點擊事件,當咱們點擊按鈕時,會彈出什麼提示框呢?
很容易犯錯,對是的,三個按鈕都是彈出:"Button4",你答對了嗎?
當註冊事件結束後,i的值爲4,當點擊按鈕時,事件函數即function(){ alert("Button"+i);}這個匿名函數中沒有i,根據做用域鏈,因此到buttonInit函數中找,此時i的值爲4,
因此彈出」button4「。
附: 使用閉包 保存變量
四:with語句
說到做用域鏈,不得不說with語句。with語句主要用來臨時擴展做用域鏈,將語句中的對象添加到做用域的頭部。
一、 JavaScript沒有代碼塊做用域的概念,局部做用域是針對函數來講的。
二、 若是不使用var聲明的變量,默認爲全局變量