提到做用域,有一句話你們(有js開發經驗者)可能比較熟悉:「javascript沒有塊級做用域」。所謂「塊」,就是大括號「{}」中間的語句。例如if語句:javascript
再好比for語句:html
因此,咱們在編寫代碼的時候,不要在「塊」裏面聲明變量,要在代碼的一開始就聲明好了。以免發生歧義。如:前端
其實,你光知道「javascript沒有塊級做用域」是徹底不夠的,你須要知道的是——javascript除了全局做用域以外,只有函數能夠建立的做用域。java
因此,咱們在聲明變量時,全局代碼要在代碼前端聲明,函數中要在函數體一開始就聲明好。除了這兩個地方,其餘地方都不要出現變量聲明。並且建議用「單var」形式。jquery
jQuery就是一個很好的示例:web
下面繼續說做用域。做用域是一個很抽象的概念,相似於一個「地盤」面試
如上圖,全局代碼和fn、bar兩個函數都會造成一個做用域。並且,做用域有上下級的關係,上下級關係的肯定就看函數是在哪一個做用域下建立的。例如,fn做用域下建立了bar函數,那麼「fn做用域」就是「bar做用域」的上級。json
做用域最大的用處就是隔離變量,不一樣做用域下同名變量不會有衝突。例如以上代碼中,三個做用域下都聲明瞭「a」這個變量,可是他們不會有衝突。各自的做用域下,用各自的「a」。閉包
說到這裏,我們又能夠拿出jquery源碼來說講了。app
jQuery源碼的最外層是一個自動執行的匿名函數:
爲何要這樣作呢?
緣由就是在jQuery源碼中,聲明瞭大量的變量,這些變量將經過一個函數被限制在一個獨立的做用域中,而不會與全局做用域或者其餘函數做用域的同名變量產生衝突。
全世界的開發者都在用jQuery,若是不這樣作,極可能致使jQuery源碼中的變量與外部javascript代碼中的變量重名,從而產生衝突。
做用域這塊只是很很差解釋,我們就小步快跑,一步一步慢慢展現給你們。
下一節將把做用域和執行上下文環境結合起來講一說。
可見,要理解閉包,不是一兩句話能說清楚的。。。
---------------------------------------------------------------------------
本文已更新到《深刻理解javascript原型和閉包系列》的目錄,更多內容可參見《深刻理解javascript原型和閉包系列》。
另外,歡迎關注個人微博。
學習做者教程:《前端JS高級面試》《前端JS基礎面試題》《React.js模擬大衆點評webapp》《zepto設計與源碼分析》《json2.js源碼解讀》