關於js的變量,開始的時候咱們都會被告知,變量聲明應該在引用該變量以前。關於爲何要這樣作呢,開始的時候本着會用就行的目的,也沒去深究。不事後來常常會發現一些讓人很費解的。。姑且稱爲現象吧。先看一段代碼再說:html
function a(){ alert(a); var a = 'b' } a();//undefined
此時就會發現不遵照規則的下場了,結果不是你想要的。。固然咱們不能說只知道要怎麼寫就好了。要知其然也要知其因此然,究其緣由,就涉及到兩個概念js做用域和詞法分析了。c++
都知道js中不存在相似於c++等語言的塊級做用域,例如for循環中定義的變量,實際上是屬於當前對象下的屬性,同一對象下能夠隨便訪問。只有函數能夠限定一個變量的做用範圍,即函數纔是變量的做用域。對於函數的變量訪問時遵循做用域鏈的。函數
js自上而下的執行過程分爲兩個詞法分析和執行兩個階段:詞法分析主要包括:分析形參、分析變量聲明、分析函數聲明三個部分(具體關於js詞法分析這裏知識簡單說明,請查看個人另外一篇文章http://www.cnblogs.com/pqjwyn/p/5365532.html)。經過詞法分析將咱們寫的js代碼轉成能夠執行的代碼,接下來纔是執行。post
通過詞法分析的後兩個步驟,會將存在的變量聲明和函數聲明,進行一番處理。具體拿上面的代碼作個例子(只分析變量的部分):學習
一、分析形參:此處沒有,直接略過(本文只分析變量部分,要是要看完整的部分能夠轉到http://www.cnblogs.com/pqjwyn/p/5365532.html)spa
二、分析變量聲明:此處存在var a = 'b'; 則會給當前函數活動對象(obj)增長屬性a,即:obj.a = undefined。code
語法分析以後的結果以下:htm
function a(){ var a = undefined;//詞法分析以後的結果 alert(a); a = 'b' } a();//undefined
接下來就是執行的過程了,什麼你說alert()語句呢?詞法分析顧名思義只分析詞法相關的部分即變量聲明之類的,做爲一個執行語句,只有在執行的過程纔會執行。也就是說該過程和執行語句還沒扯上關係呢,下面執行步驟的時候纔會出場。對象
因此執行的時候自上而下的順序執行時,當執行到alert(a);時,真正的賦值語句還在下面,因此是undefined。blog
我好像忘了說變量提高的概念了,其實上面的就是變量提高的實例了,概念就不去下定義了。你們都知道的。再提一句函數提高,詞法分析的時候關於函數聲明的處理與變量聲明的處理不太一致,會一步到位的給當前函數活動對象增長對應函數名的屬性,並重寫該方法。也就是不會像變量那樣先賦值undefined了。說的有點繞,咱們仍是看代碼,能夠先本身看一下執行結果,再看下面的分析:
function a(){ var b = 'a'; function b(){ console.log('b') } alert(b) } a()
簡單說下,詞法分析時對function b的處理:給當前函數活動對象obj增長屬性b,並賦值。即:obj.a = function(){...}
因此詞法分析後的結果成了這個樣子:
function a(){ var b = undefined; b = function b(){ console.log('b') } b = 'a'; alert(b) } a()
而後順序執行的結果也就出來了,b被從新賦值兩次以後的結果爲'a'
到此爲止,關於變量提高的部分已經結束了。仍是那句話,我的愚見,拋磚引玉,共同窗習,共同進步。轉載請註明出處。