摘要:為什么呢函數(shù)式編程能使代碼更具可預(yù)測性,確定性,更安全,一旦習(xí)慣這種方式,代碼會更容易維護(hù)。第二個(gè)建議創(chuàng)建局部函數(shù)即使是在已經(jīng)存在的函數(shù)中來說明代碼的功能,不需要使用注釋。注意,三個(gè)局部函數(shù)不修改它們的執(zhí)行上下文。
原文作者:Sébastien Castiel
原文鏈接:Writing modern JavaScript code
說點(diǎn)什么:這是一篇很樸素的文章,講的道理都懂,但實(shí)際上,在工作中遇到類似的情形卻未必如此,編寫可維護(hù),可閱讀,更安全的代碼是我們應(yīng)有的責(zé)任。
是不是還認(rèn)為 JavaScript 是一門用于在光標(biāo)懸浮時(shí)改變頁面元素的語言?這些日子已經(jīng)不復(fù)存在,每一種語言都在隨著時(shí)間推移而發(fā)展,我們使用語言的方式同樣也在發(fā)展。看一下你一兩年前寫的代碼:會感到羞愧嗎?如果是的話,這篇文章應(yīng)該很適合你。
這里會列出一些所謂的最佳實(shí)踐,目的是讓你的 JavaScript 代碼更容易編寫,閱讀和維護(hù)。
使用可格式化代碼的 linter第一個(gè)建議是使用 linter 工具,可以幫助你檢查在不同文件是否遵守一致的規(guī)則,尤其是當(dāng)不同開發(fā)人員在同一個(gè)項(xiàng)目上工作:縮進(jìn),括號中的空格,替換 == 為 === ...
但更重要的是,盡可能使用 linter 工具自動修復(fù)代碼。ESLint 就做得很好(帶有 --fix 選項(xiàng)),而且與所有主流 IDE 完美集成,可以在保存時(shí)自動修復(fù)文件。
還可以使用 Prettier,不過這款工具更注重格式化而不是靜態(tài)檢查,但處理后的結(jié)果基本相同。
下一步將介紹與 linter 工具一起使用的規(guī)則:
為你的 linter 定制現(xiàn)代化的規(guī)則如果不知道你的代碼需要什么樣的規(guī)則,可以參考:StandardJS。這是一個(gè)非常嚴(yán)格的 linter,無法修改配置,但里面的每一條規(guī)則已經(jīng)越來越多地被社區(qū)接納。比如:
使用 2 個(gè)空格縮進(jìn)(我曾經(jīng)使用 4 個(gè)空格,但實(shí)際使用起來 2 個(gè)空格很不錯(cuò))
不使用分號(一開始可能會覺得奇怪,但幾天后就再也回不去了)
在關(guān)鍵字(如 if)和花括號使用空格,在括號不使用空格
等等。
StandardJS 是一個(gè)獨(dú)立的 Node 模塊,可以進(jìn)行 lint 和修復(fù)代碼,但如果要在現(xiàn)有的大型項(xiàng)目中使用,并且想要停用一些規(guī)則(因?yàn)橛行┑胤娇赡苄枰鞔罅啃薷模?,還可以使用 ESLint 預(yù)定配置。比如,我就停用了規(guī)則 no-mixed-operators 和 import / no-webpack-loader-syntax。
使用 ES2015+ 的新特性如果你在使用 JavaScript 開發(fā),根本沒辦法不聽說 ES2015 +(或 ES6,ES7 ...)的特性。有的已經(jīng)是我離不開的:
箭頭函數(shù):對于函數(shù)式編程,比如寫 x => x * 2 這樣的函數(shù)非常有用(見下一點(diǎn))
類:停止使用原型函數(shù),使用類更酷炫(但不要濫用,JavaScript 比任何面向?qū)ο蟮恼Z言好多了)
對數(shù)組和對象的操作:
function doSomething() { const a = doSomethingElse() const b = doSomethingWithA(a) const otherResults = { c: "?", d: "?" } return { a, b, ...otherResults } // equivalent to { a: a, b: b } } const { a, c, ...rest } = doSomething() // Also works with arrays! // `rest` looks like { b: ..., d: "?" }
使用 async/await 編寫更簡單的異步處理:
// Please try to write the same code with classic promises ;) async function doSomething() { const a = await getValueForA() const b = await getValueForBFromA(a) const [c, d] = await Promise.all([ // parallel execution getValueForC(), getValueForDFromB(b) ]) const total = await calculateTotal(a, b, c, d) return total / 1000 }
想知道如何使用這些特性呢?我的另一篇文章能給一些建議。(順便說一下,使用最新版本的 Node.js,可能不再需要 Babel 就能使用這些新特性)
使用函數(shù)式編程函數(shù)式編程最近很熱門,取得不少成就,而且不僅僅是在 JavaScript 中。為什么呢?函數(shù)式編程能使代碼更具可預(yù)測性,確定性,更安全,一旦習(xí)慣這種方式,代碼會更容易維護(hù)。這里有一些簡單的建議:
首先,停止使用 for 循環(huán),在大多數(shù)(可能是所有?)情況下根本不需要。例如:
const arr = [{ name: "first", value: 13 }, { name: "second", value: 7 }] // Instead of: const res = {} for (let i = 0; i < arr.length; i++) { const calculatedValue = arr[i].value * 10 if (calculatedValue > 100) { res[arr[i].name] = calculatedValue } } // Prefer: const res = arr .map(elem => ({ name: elem.name, calculatedValue: elem.value * 10 })) .filter(elem => elem.calculatedValue > 100) .reduce((acc, elem) => ({ [elem.name]: elem.calculatedValue, ...acc }), {})
好吧,這實(shí)際上是一個(gè)非常極端的例子,對于不習(xí)慣函數(shù)式編程的人而言,可能看起來更加復(fù)雜。但我們可以稍微簡化一下:
const enrichElementWithCalculatedValue = elem => ({ name: elem.name, calculatedValue: elem.value * 10 }) const filterElementsByValue = value => elem => elem.calculatedValue > value const aggregateElementInObject = (acc, elem) => ({ [elem.name]: elem.calculatedValue, ...acc }) const res = arr .map(enrichElementWithCalculatedValue) .filter(filterElementsByValue(100)) .reduce(aggregateElementInObject, {})
在這里,我們定義了三個(gè)函數(shù),其功能基本上與其名字一致。第二個(gè)建議:創(chuàng)建局部函數(shù)(即使是在已經(jīng)存在的函數(shù)中)來說明代碼的功能,不需要使用注釋。
注意,三個(gè)局部函數(shù)不修改它們的執(zhí)行上下文。沒有外部變量被修改,沒有其他服務(wù)被調(diào)用...在函數(shù)式編程中,它們被稱為純函數(shù)。純函數(shù)具有很大的優(yōu)勢:
很容易測試,因?yàn)閺慕o定參數(shù)只有一個(gè)可能的結(jié)果,不管被調(diào)用了多少次;
無論應(yīng)用狀態(tài)如何,都能保證相同的結(jié)果;
應(yīng)用狀態(tài)在函數(shù)調(diào)用之前和之后保持不變。
所以我的第三個(gè)建議是:盡可能地使用純函數(shù)。
其他的一些建議習(xí)慣于使用異步代碼,并多使用 promise,看看 RxJS 的 observales(有一個(gè)很棒的教程關(guān)于從函數(shù)式編程到響應(yīng)式編程)
寫測試!這應(yīng)該是很明顯的,但是據(jù)我所知很多項(xiàng)目都有未經(jīng)測試的代碼,盡管測試 JavaScript(前端或后端)并不困難。
使用最新的語言特性:比如不要再寫 arr.indexOf(elem) !== -1,而應(yīng)該寫成 arr.includes(elem)。
大量閱讀技術(shù)文章:JavaScript subreddit 是了解目前社區(qū)最酷做法的一個(gè)很好的來源。
總而言之,最好的建議就是:總是重構(gòu)你的代碼。比如改進(jìn)你一年前寫過的模塊?借此機(jī)會,用 const 取代 var,使用箭頭函數(shù)或 async/await 簡化代碼......和你喜歡的代碼工作一件很愉悅的事。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/83300.html
摘要:在拿到這塊內(nèi)存后,是擁有完全操作的權(quán)利的。后面定義了一個(gè)函數(shù),并導(dǎo)出為函數(shù)。首先,使用在棧內(nèi)壓入一個(gè)位整型常數(shù),然后使用在棧內(nèi)壓入一個(gè)位整型常數(shù),之后調(diào)用指令,這個(gè)指 前端開發(fā)人員想必對現(xiàn)代瀏覽器都已經(jīng)非常熟悉了吧?HTML5,CSS4,JavaScript ES6,這些已經(jīng)在現(xiàn)代瀏覽器中慢慢普及的技術(shù)為前端開發(fā)帶來了極大的便利。得益于 JIT(Just-in-time)技術(shù),Java...
摘要:巔峰人生年老兵思路上的轉(zhuǎn)變,遠(yuǎn)比單純提升技術(shù)更有價(jià)值本文節(jié)選自趙成教授在極客時(shí)間開設(shè)的趙成的運(yùn)維體系管理課,是其對自己十年技術(shù)生涯的回顧與總結(jié)。趙成教授來自美麗聯(lián)合集團(tuán),集團(tuán)旗下兩大主力產(chǎn)品是蘑菇街和美麗說,目前負(fù)責(zé)管理集團(tuán)的技術(shù)服務(wù)團(tuán)隊(duì)。 showImg(https://segmentfault.com/img/remote/1460000012476504?w=1240&h=826...
摘要:前端每周清單專注前端領(lǐng)域內(nèi)容,以對外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn)分為新聞熱點(diǎn)開發(fā)教程工程實(shí)踐深度閱讀開源項(xiàng)目巔峰人生等欄目。背后的故事本文是對于年之間世界發(fā)生的大事件的詳細(xì)介紹,闡述了從提出到角力到流產(chǎn)的前世今生。 前端每周清單專注前端領(lǐng)域內(nèi)容,以對外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn);分為新聞熱點(diǎn)、開發(fā)教程、工程實(shí)踐、深度閱讀、開源項(xiàng)目、巔峰人生等欄目。歡迎...
摘要:文檔翻譯系列一安裝原文地址原文本系列是針對文檔進(jìn)行的翻譯,因?yàn)樽约涸趯W(xué)習(xí)的時(shí)候,最開始通過看博客或者論壇等中文資料,有些內(nèi)容是零零散散的接收,并沒有給自己帶來很好的效果,所以后來決定把文檔的原文從頭到尾看一遍。 React文檔翻譯系列(一)安裝 原文地址:原文 本系列是針對React文檔進(jìn)行的翻譯,因?yàn)樽约涸趯W(xué)習(xí)react的時(shí)候,最開始通過看博客或者論壇等中文資料,有些內(nèi)容是零零散散的...
摘要:的另一個(gè)核心特性,蘋果表示也正在開發(fā)中,按開發(fā)進(jìn)度可能幾個(gè)月后就能與我們見面。是基于的本地化數(shù)據(jù)庫,支持以及瀏覽器環(huán)境。 前端每周清單專注前端領(lǐng)域內(nèi)容,以對外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn);分為新聞熱點(diǎn)、開發(fā)教程、工程實(shí)踐、深度閱讀、開源項(xiàng)目、巔峰人生等欄目。歡迎關(guān)注【前端之巔】微信公眾號(ID: frontshow),及時(shí)獲取前端每周清單。 本期是 2017 年的最后一...
閱讀 2680·2023-04-25 18:10
閱讀 1619·2019-08-30 15:53
閱讀 2817·2019-08-30 13:10
閱讀 3231·2019-08-29 18:40
閱讀 1137·2019-08-23 18:31
閱讀 1210·2019-08-23 16:49
閱讀 3410·2019-08-23 16:07
閱讀 885·2019-08-23 15:27