如下代碼:
if (true) {
// 在某個(gè)條件分支下創(chuàng)建一個(gè)函數(shù),并且只在這個(gè)分支內(nèi)使用。
function a() {
// code...
}
a();
}
// 報(bào)錯:
"Move function declaration to program root. (no-inner-declarations)"
要把函數(shù)定義在整個(gè)文檔的最外層才行。我在網(wǎng)上搜索看到的說法是:
ES6以前,函數(shù)聲明只能在程序或另一個(gè)函數(shù)體的最前面,所以在代碼塊內(nèi)部聲明函數(shù)是錯誤的做法。另外,由于 javascript 中代碼聲明會被提升到代碼當(dāng)前作用域的最前面,所以在代碼塊內(nèi)聲明變量也是不明智的做法
是不是在ES6之前,這樣聲明是語法錯誤?另外,我會把這個(gè)函數(shù)保持在它被調(diào)用之前,這樣就不會發(fā)生變量提升了。
其實(shí)我很郁悶,因?yàn)槲业拇a要根據(jù)不同場景執(zhí)行不同的代碼,有些函數(shù)只在某一個(gè)場景下使用。按照這個(gè)標(biāo)準(zhǔn)的話要把大量函數(shù)移出來,結(jié)果就是聲明的這些函數(shù)有很多根本沒有被調(diào)用。這樣是不是會多占用資源?
1、題主第一個(gè)問題:想這樣:
在某個(gè)條件分支下創(chuàng)建一個(gè)函數(shù),并且只在這個(gè)分支內(nèi)使用。
所以寫出下面代碼:
if (true) {
// 在某個(gè)條件分支下創(chuàng)建一個(gè)函數(shù),并且只在這個(gè)分支內(nèi)使用。
function a() {
// code...
}
a();
}
但是,題主如果在 if 語句塊之外訪問函數(shù) a,是可以的,因?yàn)?/p>
ES6 在非嚴(yán)格模式下塊級函數(shù)的作用域會被提升到所在函數(shù)或全局環(huán)境的頂部,而不是代碼塊的頂部。
所以下面代碼不會報(bào)錯:
if (true) {
// 在某個(gè)條件分支下創(chuàng)建一個(gè)函數(shù),并且只在這個(gè)分支內(nèi)使用。
function a() {
// code...
}
a();
}
a;//返回函數(shù) a
所以,題主想要的
在某個(gè)條件分支下創(chuàng)建一個(gè)函數(shù),并且只在這個(gè)分支內(nèi)使用
在非嚴(yán)格模式下,并沒有實(shí)現(xiàn),或者說,看起來實(shí)現(xiàn)了,但實(shí)際上沒有,反而造成了全局變量污染且容易引起歧義;
在嚴(yán)格模式下,是實(shí)現(xiàn)了的,也就是說,上面的函數(shù) a 只能在 if 語句塊內(nèi)訪問,因?yàn)?/p>
ES6 會將 a() 函數(shù)視為塊級聲明,并允許它在定義所在的代碼塊內(nèi)部被訪問,且塊級函數(shù)會被提升到所在代碼塊的頂部
2、題主的第二個(gè)問題:
是不是在ES6之前,這樣聲明是語法錯誤?
答:
在 ES3 或更早版本中,在代碼塊中聲明函數(shù)(即塊級函數(shù))嚴(yán)格來說應(yīng)當(dāng)是一個(gè)語法錯誤,但所有的瀏覽器卻都支持該語法??上У氖牵總€(gè)支持該語法的瀏覽器都有輕微的行為差異,所以最佳實(shí)踐就是不要在代碼塊中聲明函數(shù)(更好的選擇是使用函數(shù)表達(dá)式)。為了控制這種不兼容行為, ES5 的嚴(yán)格模式為代碼塊內(nèi)部的函數(shù)聲明引入了一個(gè)錯誤
3、題主的第三個(gè)問題:
另外,我會把這個(gè)函數(shù)保持在它被調(diào)用之前,這樣就不會發(fā)生變量提升了。
題主請先去了解下函數(shù)聲明語句的變量提升,題主的這句話代表題主并不理解變量提升;
4、題主的第四個(gè)問題:
其實(shí)我很郁悶,因?yàn)槲业拇a要根據(jù)不同場景執(zhí)行不同的代碼,有些函數(shù)只在某一個(gè)場景下使用。按照這個(gè)標(biāo)準(zhǔn)的話要把大量函數(shù)移出來,結(jié)果就是聲明的這些函數(shù)有很多根本沒有被調(diào)用。這樣是不是會多占用資源?
這個(gè)不太清楚,我粗淺的認(rèn)為不會,因?yàn)?js 有垃圾回收機(jī)制,如果沒有閉包,正常情況下都會被垃圾回收掉的,閉包題主請單獨(dú)查資料,或者戳這
重新回答一份
1.ESLint只是一個(gè)代碼檢查工具,它報(bào)錯不代表代碼是錯誤的
2.ESLint的提示都是有原因的
3.在代碼塊兒中定義函數(shù)自己使用的做法很常見,不喜歡提示可以關(guān)掉這個(gè)選項(xiàng)
4.如果“提升”整個(gè)概念是指編譯階段將所有的聲明都挪到執(zhí)行代碼的前面,那我可以接受。為什么會將聲明的部分提到最前面,我覺得應(yīng)該是方便申請內(nèi)存吧。
5.我也不支持在代碼塊(尤其是邏輯分支)中定義自己使用的函數(shù)。如果你能確定這個(gè)方法絕對沒有地方再使用,大可這么做,語法也支持,協(xié)作起來也只有你自己知道這段代碼并維護(hù)。
6.方法定義在哪里都一樣,代碼體積也不會變,也省不了多少內(nèi)存。在邏輯分支里定義了函數(shù)基本上也會馬上調(diào)用,理論上修改起來并不方便。
寫在后面:這個(gè)語法是沒有錯誤的,但是是存在的隱患的,所以ESLint告訴你不要這么做。你擔(dān)心的占用資源問題是多余的,方法執(zhí)行起來占用的資源才是你應(yīng)該擔(dān)心的。另外考慮到復(fù)用性和協(xié)作,即使是不同分支要執(zhí)行不同代碼,也不要在代碼塊兒內(nèi)聲明方法。復(fù)用性上不便于方法的復(fù)用,協(xié)作性上不便于別人修改你的代碼。如果說需求是根據(jù)不同的條件需要不同的方法體,那為什么不把這個(gè)條件作為參數(shù)傳入方法,在方法體中進(jìn)行邏輯分支。ESLint給出的提示是根據(jù)設(shè)計(jì)模式和代碼規(guī)范給出的,完全按照提示去做絕對沒有壞處,不按照他說的做也不一定會報(bào)錯。養(yǎng)成良好的代碼習(xí)慣,學(xué)會去構(gòu)建代碼,而不是一味地實(shí)現(xiàn)邏輯,這也是ESLint這樣的工具存在的目的。
北大青鳥APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國家
達(dá)內(nèi)教育集團(tuán)成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機(jī)構(gòu),是中國一站式人才培養(yǎng)平臺、一站式人才輸送平臺。2014年4月3日在美國成功上市,融資1
北大課工場是北京大學(xué)校辦產(chǎn)業(yè)為響應(yīng)國家深化產(chǎn)教融合/校企合作的政策,積極推進(jìn)“中國制造2025”,實(shí)現(xiàn)中華民族偉大復(fù)興的升級產(chǎn)業(yè)鏈。利用北京大學(xué)優(yōu)質(zhì)教育資源及背
博為峰,中國職業(yè)人才培訓(xùn)領(lǐng)域的先行者
曾工作于聯(lián)想擔(dān)任系統(tǒng)開發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項(xiàng)目經(jīng)理從事移動互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
浪潮集團(tuán)項(xiàng)目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺面向?qū)ο箝_發(fā)經(jīng)驗(yàn),技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點(diǎn)難點(diǎn)突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫,具有快速界面開發(fā)的能力,對瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁制作和網(wǎng)頁游戲開發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開發(fā)經(jīng)驗(yàn)。曾經(jīng)歷任德國Software AG 技術(shù)顧問,美國Dachieve 系統(tǒng)架構(gòu)師,美國AngelEngineers Inc. 系統(tǒng)架構(gòu)師。