提到作用域,有一句話大家(有js開發(fā)經(jīng)驗(yàn)者)可能比較熟悉:“javascript沒有塊級(jí)作用域”。所謂“塊”,就是大括號(hào)“{}”中間的語句。例如if語句:
再比如for語句:
所以,我們在編寫代碼的時(shí)候,不要在“塊”里面聲明變量,要在代碼的一開始就聲明好了。以避免發(fā)生歧義。如:
其實(shí),你光知道“javascript沒有塊級(jí)作用域”是完全不夠的,你需要知道的是——javascript**除了全局作用域之外,只有函數(shù)可以創(chuàng)建的作用域**。
所以,我們在聲明變量時(shí),全局代碼要在代碼前端聲明,函數(shù)中要在函數(shù)體一開始就聲明好。除了這兩個(gè)地方,其他地方都不要出現(xiàn)變量聲明。而且建議用“單var”形式。
jQuery就是一個(gè)很好的示例:
下面繼續(xù)說作用域。作用域是一個(gè)很抽象的概念,類似于一個(gè)“地盤”
如上圖,全局代碼和fn、bar兩個(gè)函數(shù)都會(huì)形成一個(gè)作用域。而且,作用域有上下級(jí)的關(guān)系,上下級(jí)關(guān)系的確定就看函數(shù)是在哪個(gè)作用域下創(chuàng)建的。例如,fn作用域下創(chuàng)建了bar函數(shù),那么“fn作用域”就是“bar作用域”的上級(jí)。
作用域最大的用處就是隔離變量,不同作用域下同名變量不會(huì)有沖突。例如以上代碼中,三個(gè)作用域下都聲明了“a”這個(gè)變量,但是他們不會(huì)有沖突。各自的作用域下,用各自的“a”。
說到這里,咱們又可以拿出jquery源碼來講講了。
jQuery源碼的最外層是一個(gè)自動(dòng)執(zhí)行的匿名函數(shù):
為什么要這樣做呢?
原因就是在jQuery源碼中,聲明了大量的變量,這些變量將通過一個(gè)函數(shù)被限制在一個(gè)獨(dú)立的作用域中,而不會(huì)與全局作用域或者其他函數(shù)作用域的同名變量產(chǎn)生沖突。
全世界的開發(fā)者都在用jQuery,如果不這樣做,很可能導(dǎo)致jQuery源碼中的變量與外部javascript代碼中的變量重名,從而產(chǎn)生沖突。
作用域這塊只是很不好解釋,咱們就小步快跑,一步一步慢慢展示給大家。
下一節(jié)將把作用域和執(zhí)行上下文環(huán)境結(jié)合起來說一說。
可見,要理解閉包,不是一兩句話能說清楚的。。。
更多建議: