關於變量提高,之前在一些教程和書籍上都聽到過,平時開發中也知道有這個規律,可是今天忽然在一個公開課中聽到時,第一反應時一臉懵逼,而後一百度,瞬間以爲好熟悉啊,差點被這個概念給唬住了,不信我給你看個栗子,你也會恍然大悟的:html
(function(){ console.log(v); var v = 'I love you'; console.log(v); })() // undefined I love you
這就是一個典型的變量提高的例子了,規則是怎樣的呢,個人理解是在一個做用域內,不管你在哪一個地方聲明的變量都會被提高到頂部,但不會賦值。像本例子中的v就是先被提高到了函數做用域的頂端,因此實際運行過程是這樣的:函數
(function(){ var v = undefined; console.log(v); v = 'I love you'; console.log(v); })() // undefined I love you
爲何會這樣呢,我參考了別人的解釋是由於js的運行機制:ui
js自上而下的執行過程分爲兩個詞法分析和執行兩個階段:詞法分析主要包括:分析形參、分析變量聲明、分析函數聲明三個部分.經過詞法分析將咱們寫的js代碼轉成能夠執行的代碼,接下來纔是執行。code
變量提高還有一種狀況,就是函數,詞法分析的時候關於函數聲明的處理與變量聲明的處理不太一致,會一步到位的給當前函數活動對象增長對應函數名的屬性,並重寫該方法。也就是不會像變量那樣先賦值undefined了。說的有點繞,咱們仍是看代碼,能夠先本身看一下執行結果,再看下面的分析:htm
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 } a()
這個地方也只是我讀別人觀點的一種借鑑,可是我有點不太肯定的是普通變量提高和函數提高同時進行時到底誰在最頂端?反正就目前個人認識變量提高的規律是清楚了,大提高提高的原理是由於JS運行機制的問題,爲了儘可能避免變量提高帶來的一些困擾,平常開發中文名仍是要養成先聲明再使用的好習慣,儘可能在函數開頭把全部變量都聲明出來。文中觀點大都是我的理解,若有不對,歡迎指出!blog