javascript
JavaScript 进阶(二)变量作用域
局部變量陷阱
先看一段代碼:
這個(gè)函數(shù)執(zhí)行完成之后返回helloworld,結(jié)果確實(shí)沒(méi)有問(wèn)題。但是里面有一個(gè)細(xì)節(jié)就是兩個(gè)局部變量一個(gè)前邊有var,另一個(gè)沒(méi)有。這似乎并不影響執(zhí)行,但是事實(shí)上沒(méi)有var的話,這個(gè)變量就變成了全局變量。你在這個(gè)函數(shù)外面調(diào)用一下alert(b)試一下就知道了。一個(gè)莫名其妙冒出來(lái)的全局變量在有時(shí)候會(huì)引起匪夷所思的bug,所以一定要記得局部變量聲明前一定要用var
變量聲明提升
再看一段代碼:
代碼執(zhí)行時(shí),請(qǐng)問(wèn)alert的內(nèi)容是什么呢?答案是undefined。從直覺(jué)上來(lái)講,運(yùn)行alert的時(shí)候,foo這個(gè)變量沒(méi)有聲明,不存在。既然局部作用域沒(méi)有,那就去全局作用域找,應(yīng)該是"hello"才是啊。為什么呢?這就是變量聲明提升。函數(shù)內(nèi)的任何變量的聲明都會(huì)被提升至函數(shù)的頂部,所以上面的test函數(shù)相當(dāng)于
所以會(huì)是undefined。這里注意提升的只是聲明,賦值的代碼還在原來(lái)的地方。并且聲明的部分與聲明的代碼是否執(zhí)行無(wú)關(guān),比如
把test函數(shù)修改成這個(gè)樣子,執(zhí)行結(jié)果仍然是一樣。聲明仍然被提前了,盡管這行代碼將不會(huì)被運(yùn)行。
這就是變量聲明提升,我們?cè)倏匆粋€(gè)例子
當(dāng)test函數(shù)執(zhí)行的時(shí)候,結(jié)果如何呢?結(jié)果是foo1被alert出來(lái),然后JS報(bào)錯(cuò)"undefined is not a function"。這里在函數(shù)內(nèi)部聲明函數(shù)的提升有點(diǎn)區(qū)別。foo1,用函數(shù)的方式聲明定義一個(gè)函數(shù),則聲明與函數(shù)體都被提升了,但是foo2用變量的方式定義函數(shù),被提升的只有聲明,函數(shù)體沒(méi)有被提升,所以執(zhí)行foo2()的時(shí)候,foo2沒(méi)有被賦值,是undefined。
看起來(lái)由于JS里面有變量聲明提升,那么就無(wú)法使用C語(yǔ)言里面的塊級(jí)作用域,那么我確實(shí)想用,怎么辦呢?有一個(gè)辦法是用匿名函數(shù),舉例如下:
當(dāng)test函數(shù)改成這個(gè)樣子的時(shí)候,alert出來(lái)的結(jié)果就是"hello"了,匿名函數(shù)里面的foo就無(wú)法作用到其他地方。
閉包中的局部變量
我之前招聘前端,問(wèn)了應(yīng)聘者這樣一個(gè)題目,說(shuō)請(qǐng)寫一個(gè)可以返回遞增整數(shù)序列的函數(shù),他給我的答案是這樣
當(dāng)反復(fù)調(diào)用函數(shù)increase的時(shí)候,就會(huì)返回遞增序列。但是我接著問(wèn),如果有人失手改了i怎么樣,他語(yǔ)塞。其實(shí)這個(gè)問(wèn)題的關(guān)鍵是說(shuō)要制造一個(gè)很安全的地方來(lái)放置這個(gè)i,讓這個(gè)變量只能被一個(gè)函數(shù)訪問(wèn),所以一個(gè)可選的答案是這樣。此時(shí)increase就是會(huì)返回遞增序列。并且i放在了一個(gè)很安全的地方。就不會(huì)被破壞了。
JS的閉包是一個(gè)很值得講的內(nèi)容,好用,但是也有不少坑,下面我專門開(kāi)一篇文章來(lái)講。
全局變量
無(wú)數(shù)講高質(zhì)量代碼的書籍都會(huì)提到全局變量這個(gè)大殺器,程序員們都被反復(fù)告誡,除非你又充足的理由,否則不要使用全局變量,JS也不例外。然而JS有一個(gè)特殊的地方就是沒(méi)有main方法,入口的代碼一定要寫,但是寫在這地方的代碼難免要用到變量,這些變量就是全局變量了,那么如何處理這個(gè)問(wèn)題呢?答案還是匿名函數(shù),像這樣:
把入口代碼放到一個(gè)匿名函數(shù)中,這樣這些變量a, b, c就會(huì)被藏到這個(gè)函數(shù)里面,就避免了全局變量的出現(xiàn)。
總結(jié)
以上是生活随笔為你收集整理的JavaScript 进阶(二)变量作用域的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 小米13 Ultra手机壳曝光:中分四摄
- 下一篇: WordPress翻译更新失败解决方法