編寫更魯棒的JavaScript代碼:7個(gè)優(yōu)秀實(shí)踐
來源:Pexels
1. 編寫構(gòu)造函數(shù)時(shí),在 .prototype上添加方法
根據(jù)我頭兩年接觸JavaScript的經(jīng)歷,如果你是一名JavaScript新手,可能會(huì)對這部分有些陌生。
(請記住,這并不適用于類,因?yàn)轭愐呀?jīng)將方法附加到它們的prototype上。)
以下是構(gòu)造函數(shù)的一個(gè)示例:
- functionFrog(name, gender) {
- this.name= name
- this.gender= gender
- }
- Frog.prototype.leap=function(feet) {
- console.log(`Leaping ${feet}ft into the air`)
- }
為什么不像以下示例一樣,直接附加leap方法呢?
- functionFrog(name, gender) {
- this.name= name
- this.gender= gender
- this.leap=function(feet) {
- console.log(`Leaping ${feet}ft into the air`)
- }
- }
當(dāng)把方法直接添加到prototype時(shí),它們將在構(gòu)造函數(shù)創(chuàng)建的所有實(shí)例之間共享。
換句話說,使用上個(gè)例子,如果創(chuàng)建三個(gè)獨(dú)立的 Frog (從 this.leap = function() {...}),然后以創(chuàng)建三個(gè)獨(dú)立的副本結(jié)束。這是一個(gè)問題,因?yàn)閘eap方法總是保持不變,不需要在實(shí)例上建立自己的副本。
最終導(dǎo)致本可以避免的性能下降。this.name 和this.gender屬性需要在實(shí)例上定義,因?yàn)楝F(xiàn)實(shí)生活中,frog可能有自己的名字和性別,所以才在實(shí)例級(jí)別上創(chuàng)建它們。
這里是流行的request 包使用這種方法的一個(gè)示例(在GitHub上)。
2. 使用TypeScript
TypeScript不僅能為類型安全提供強(qiáng)大防御,還能幫助預(yù)防錯(cuò)誤,已經(jīng)在JavaScript社區(qū)中得到了廣泛應(yīng)用。
使用TypeScript能使編譯器在代碼運(yùn)行之前對潛在的錯(cuò)誤進(jìn)行監(jiān)測并顯示警告。
但這還遠(yuǎn)不能解釋為什么TypeScript可以適用于任何情況。TypeScript最好的一點(diǎn)是允許在主流瀏覽器支持之前使用JavaScript中的新特征,因?yàn)檫@些特征被編譯成更早期的JavaScript版本,因此能在舊版本的瀏覽器中運(yùn)行。
3. 編寫測試
如果要認(rèn)真處理一個(gè)項(xiàng)目,必須使用測試,這樣應(yīng)用程序才更能夠更加可預(yù)測、少出錯(cuò)、并靈活應(yīng)對未來的變化。換句話說,如果打算做一個(gè)經(jīng)得起時(shí)間考驗(yàn)的項(xiàng)目,沒有比在整個(gè)代碼中建立測試更好的方法。在代碼中投入的測試越多,將其應(yīng)用于生產(chǎn)環(huán)境后,對它的信心也會(huì)越多。
測試最好的部分是什么?是能捕捉錯(cuò)誤,使其無從出現(xiàn)——有人不想要那種能力嗎?我確定我想要。這就是我在項(xiàng)目中寫單元測試的原因。
來源:Pexels
4. 使用JSON.parse或JSON.stringify時(shí),務(wù)必考慮使用 try/catch
JavaScript中,當(dāng)把JSON作為輸入傳遞給JSON.parse時(shí),需要一個(gè)正確格式的JSON作為第一個(gè)參數(shù)。如果格式不正確,會(huì)提示JSON解析錯(cuò)誤。
來自JSON解析錯(cuò)誤的危險(xiǎn)是接受無效的JSON會(huì)導(dǎo)致應(yīng)用程序崩潰。最近我們的一個(gè)web項(xiàng)目失敗了,因?yàn)榱硪粋€(gè)內(nèi)置程序包沒有在try/catch里安裝JSON.parse 。最終導(dǎo)致了web頁面失效,而且由于JavaScript運(yùn)行時(shí)被破壞,除非內(nèi)置程序包修復(fù)它,否則無法修正錯(cuò)誤。
- SyntaxError: Unexpected token }in JSON at position 107
不應(yīng)總是期望有效的JSON輸入,因?yàn)樗鼤?huì)收到如“>”的奇怪字符,這在今天是很常見的。
5. 使用常規(guī)的.type屬性進(jìn)行區(qū)分
這個(gè)方法很棒,得到了廣泛使用。React開發(fā)人員可能每天都能看到這種做法,特別是使用Redux工作時(shí)。
使用類似方法也能使開發(fā)流程變得無比簡單,因?yàn)樗踔量梢院芎玫挠涗涀约骸?/p>
- functioncreateSpecies(type, name, gender) {
- if (type ==='frog') {
- returncreateFrog(name, gender)
- } elseif (type ==='human') {
- returncreateHuman(name, gender)
- } elseif (type == undefined) {
- thrownewError('Cannot create a species with an unknown type')
- }
- }
- const myNewFrog =createSpecies('frog', 'sally', 'female')
6. 使用工廠函數(shù)(factory function)
如果你不知道什么是工廠函數(shù),那么它就是一個(gè)返回對象的函數(shù)(它既不是類,也不是構(gòu)造函數(shù))。通過這個(gè)簡單概念,就可以利用JavaScript及其特征來創(chuàng)建強(qiáng)大健壯的應(yīng)用程序。
必須知道,當(dāng)函數(shù)被new關(guān)鍵字調(diào)用時(shí),該函數(shù)就不再是工廠函數(shù)了。
為什么要用工廠函數(shù)?
使用工廠函數(shù)可以輕松的生成對象實(shí)例,且無需涉及類或new關(guān)鍵字。
其本質(zhì)上意味著,它們最終會(huì)被當(dāng)做函數(shù)來對待,即可用于組合對象、函數(shù),甚至Promise函數(shù)。這表明可以將工廠函數(shù)混合搭配,以創(chuàng)建一個(gè)升級(jí)版工廠函數(shù),然后繼續(xù)和別的函數(shù)或?qū)ο蠼M合創(chuàng)建成更強(qiáng)的工廠函數(shù)。其可能性是無窮無盡的。
考慮到這一點(diǎn),將其與好的代碼實(shí)踐相結(jié)合,它便開始大放光彩了。
以下是工廠函數(shù)的一個(gè)簡單示例:
- functioncreateFrog(name) {
- const children = []
- return {
- addChild(frog) {
- children.push(frog)
- },
- }
- }
- const mikeTheFrog =createFrog('mike')
當(dāng)使用足夠多的工廠函數(shù)后,會(huì)意識(shí)到工廠函數(shù)比類構(gòu)造函數(shù)有更強(qiáng)的可重用性。這減少了代碼量,縮短了代碼重構(gòu)時(shí)間(因?yàn)楣S函數(shù)最終會(huì)返回任意對象),縮短了從一個(gè)代碼到另一個(gè)代碼的管理時(shí)間。
來源:Pexels
7. 使函數(shù)盡可能的簡單
眾所周知,在JavaScript中很可能有同時(shí)做很多事情的大型函數(shù)。
編程新手可能覺得這是一件好事——之前當(dāng)我寫了很大篇幅可以工作的代碼后,我的自我感覺非常好。這對我來說很重要,并給予我很大信心。畢竟它能正常運(yùn)行,我就把自己的代碼有多么冗長這件事拋之腦后了。天哪,當(dāng)時(shí)太幼稚了。
如果想寫更易維護(hù)的、簡單的、少出錯(cuò)的代碼,最好使它盡量簡潔短小。代碼越簡潔,單獨(dú)測試也會(huì)越容易。
如果你更喜歡函數(shù)式編程范式,這一點(diǎn)尤其重要。函數(shù)執(zhí)行一件事就應(yīng)該把它做好,這是常識(shí)。
希望對你有用,獲得更完美的JavaScript的最佳實(shí)踐。