這篇文章主要為大家展示了“JavaScript代碼簡化的示例分析”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“JavaScript代碼簡化的示例分析”這篇文章吧。
十多年的海陵網(wǎng)站建設(shè)經(jīng)驗(yàn),針對設(shè)計、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時及時工作處理。成都全網(wǎng)營銷的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動調(diào)整海陵建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計,從而大程度地提升瀏覽體驗(yàn)。成都創(chuàng)新互聯(lián)從事“海陵網(wǎng)站設(shè)計”,“海陵網(wǎng)站推廣”以來,每個客戶項目都認(rèn)真落實(shí)執(zhí)行。1. async / await
如果你還在為回調(diào)陷阱煩惱不已,那么就應(yīng)該趕快扔掉這些2014年的代碼了。除非絕對必要(比如某個庫要求回調(diào),或者出于性能的原因),否則不要再用回調(diào)了。Promise也不錯,但當(dāng)代碼規(guī)模越來越大時,它們總是有些別扭。
我的解決方案就是async / await,能讓閱讀代碼變得更容易,代碼變得更整潔。實(shí)際上,Javascript中的任何Promise都可以await,只要你用的庫能返回Promise,就可以await它。實(shí)際上,async/await只不過是promise的語法糖而已。為了讓代碼正確運(yùn)行,你只需在函數(shù)前面加上async即可。
下面是個例子:
async function getData() { const result = await axios.get('https://dube.io/service/ping') const data = result.data console.log('data', data) return data } getData()
注意在頂層代碼是無法await的,await只能在async函數(shù)中使用。此外,async / await是在ES2017中引入的,所以務(wù)必要對代碼進(jìn)行編譯(transpile)。
2. 異步控制流
許多時候需要獲取多個數(shù)據(jù)集并在每個數(shù)據(jù)集上做一些處理,或者在所有異步調(diào)用都返回之后執(zhí)行某項任務(wù)。
for...of
假設(shè)網(wǎng)頁上有一些精靈寶可夢,我們需要獲取每一只的詳細(xì)信息。我們不能等待所有調(diào)用結(jié)束,因?yàn)槲覀儾恢酪还灿卸嗌僦?。我們希望能在獲取一部分?jǐn)?shù)據(jù)之后立即更新數(shù)據(jù)集,這時候就可以使用for...of在一個數(shù)組上進(jìn)行循環(huán),然后在內(nèi)部加入async的代碼塊,但這樣做會造成阻塞,直到所有調(diào)用結(jié)束。一定要注意,這樣做有可能會造成性能瓶頸,但這樣做也不失為一種辦法。
例子如下:
import axios from 'axios' let myData = [{id: 0}, {id: 1}, {id: 2}, {id: 3}] async function fetchData(dataSet) { for(entry of dataSet) { const result = await axios.get(`https://ironhack-pokeapi.herokuapp.com/pokemon/${entry.id}`) const newData = result.data updateData(newData) console.log(myData) } } function updateData(newData) { myData = myData.map(el => { if(el.id === newData.id) return newData return el }) } fetchData(myData)
這些例子實(shí)際上都能運(yùn)行,可以自行復(fù)制粘貼到你喜歡的代碼沙盒工具中。
Promise.all
怎樣才能并行獲取所有寶可夢呢?我們可以await所有的promise,只需用Promise.all即可:
import axios from 'axios' let myData = [{id: 0}, {id: 1}, {id: 2}, {id: 3}] async function fetchData(dataSet) { const pokemonPromises = dataSet.map(entry => { return axios.get(`https://ironhack-pokeapi.herokuapp.com/pokemon/${entry.id}`) }) const results = await Promise.all(pokemonPromises) results.forEach(result => { updateData(result.data) }) console.log(myData) } function updateData(newData) { myData = myData.map(el => { if(el.id === newData.id) return newData return el }) } fetchData(myData)
for...of和Promise.all都是在ES6+中引用的,所以代碼需要編譯。
3. 解構(gòu)和默認(rèn)值
我們現(xiàn)在回到前面的例子:
const result = axios.get(`https://ironhack-pokeapi.herokuapp.com/pokemon/${entry.id}`) const data = result.data
這段代碼有個更簡單的寫法。我們可以使用解構(gòu)來從一個數(shù)組或?qū)ο笾蝎@取一個或多個值。可以這樣寫:
const { data } = await axios.get(...)
這樣就能節(jié)省一行代碼!還可以進(jìn)行重命名:
const { data: newData } = await axios.get(...)
另一個小技巧就是在解構(gòu)時制定默認(rèn)值。這樣能保證變量永遠(yuǎn)不會為undefine,因此就不需要手工檢查變量了。
const { id = 5 } = {} console.log(id) // 5
這些技巧也可以用在函數(shù)參數(shù)上,例如:
function calculate({operands = [1, 2], type = 'addition'} = {}) { return operands.reduce((acc, val) => { switch(type) { case 'addition': return acc + val case 'subtraction': return acc - val case 'multiplication': return acc * val case 'division': return acc / val } }, ['addition', 'subtraction'].includes(type) ? 0 : 1) } console.log(calculate()) // 3 console.log(calculate({type: 'division'})) // 0.5 console.log(calculate({operands: [2, 3, 4], type: 'multiplication'})) // 24
第一眼看上去這個例子可能不太容易理解,但多花些時間研究下是有好處的。當(dāng)我們不給函數(shù)傳遞參數(shù)時,就會使用默認(rèn)值。如果給函數(shù)傳遞參數(shù),那么不存在的參數(shù)就會使用默認(rèn)值。
解構(gòu)和默認(rèn)值是在ES6+中引入的,所以代碼需要編譯。
4. 真值和假值
在使用默認(rèn)值時,經(jīng)常需要檢查存在的值。但是,你還可以直接使用真值和假值。這樣能改善代碼并節(jié)省好多字符,使代碼更加流暢。我經(jīng)??吹饺藗冞@樣寫:
if(myBool === true) { console.log(...) } // OR if(myString.length > 0) { console.log(...) } // OR if(isNaN(myNumber)) { console.log(...) }
這些代碼可以縮寫成:
if(myBool) { console.log(...) } // OR if(myString) { console.log(...) } // OR if(!myNumber) { console.log(...) }
要真正理解這些語句的好處,你必須要理解真值和假值都是什么。下面是部分摘要:
假值
長度為0的字符串
數(shù)字0
false
undefined
null
NaN
真值
空數(shù)組
空對象
任何其他東西
當(dāng)檢查真值或假值時,不需要明確寫出比較,這相當(dāng)于使用雙等號 == 而不是三等號 ===。一般來說,這種用法的行為與預(yù)想是一致的,但有可能會遇到bug。比如,我最常遇到但就是有關(guān)數(shù)字0的bug。
5. 邏輯運(yùn)算符和三元運(yùn)算符
這些運(yùn)算符也是用來縮減代碼的,節(jié)省下寶貴的代碼行數(shù)。經(jīng)常有許多工具可以保持代碼干凈整潔,但這些工具也會造成混亂,特別是在改變它們時。
邏輯運(yùn)算符
邏輯運(yùn)算符可以組合兩個表達(dá)式,并返回true或false,或者匹配的值。常用的有&&,意思是“與”,還有 || 意思是“或”。我們來看看:
console.log(true && true) // true console.log(false && true) // false console.log(true && false) // false console.log(false && false) // false console.log(true || true) // true console.log(true || false) // true console.log(false || true) // true console.log(false || false) // false
根據(jù)上一部分關(guān)于真值和假值的知識,我們可以將邏輯運(yùn)算符組合起來。在使用邏輯運(yùn)算符時,會使用以下規(guī)則:
&& :返回第一個值為假的表達(dá)式的值。如果不存在,則返回最后一個值為真的值。
|| :返回第一個值為假的表達(dá)式的值。如果不存在,則返回最后一個值為假的值。
console.log(0 && {a: 1}) // 0 console.log(false && 'a') // false console.log('2' && 5) // 5 console.log([] || false) // [] console.log(NaN || null) // null console.log(true || 'a') // true
三元運(yùn)算符
三元運(yùn)算符很像邏輯表達(dá)式,但它由三個部分組成:
比較部分,返回假值或真值;
第一個值,如果比較為真;
第二個值,如果比較為假。
下面是例子:
const lang = 'German' console.log(lang === 'German' ? 'Hallo' : 'Hello') // Hallo console.log(lang ? 'Ja' : 'Yes') // Ja console.log(lang === 'French' ? 'Bon soir' : 'Good evening') // Good evening
6. 鏈?zhǔn)讲僮?/strong>
你遇到過這個問題嗎?在訪問嵌套對象的屬性時,無法事先確定對象的屬性是否存在?可能不得不寫這樣的代碼:
let data if(myObj && myObj.firstProp && myObj.firstProp.secondProp && myObj.firstProp.secondProp.actualData) data = myObj.firstProp.secondProp.actualData
這段代碼很荒謬,我們還有更好的辦法,至少是在建議中的辦法(下面說了怎樣啟用該辦法)。這個辦法稱為optional chaining,用法如下:
const data = myObj?.firstProp?.secondProp?.actualData
用這個方法檢查嵌套屬性非常流暢,代碼也能變得更干凈。
目前,optional chaining還不是官方標(biāo)準(zhǔn)的一部分,但它是個stage-1的實(shí)驗(yàn)性功能。需要在babelrc中加入@babel/plugin-proposal-optional-chaining來啟用它。
7. 類屬性和綁定
JavaScript中的函數(shù)綁定是個非常常見的任務(wù)。由于ES6標(biāo)準(zhǔn)引入了箭頭函數(shù),我們現(xiàn)在可以自動地用定義的形式綁定函數(shù)——這方法非常好用,現(xiàn)在的JavaScript開發(fā)者都在用它。之前類剛剛出現(xiàn)時是沒辦法使用箭頭函數(shù)的,因?yàn)轭愋枰媚撤N特殊的方式來定義。我們需要在某個地方進(jìn)行綁定,例如在構(gòu)造函數(shù)里(在React.js中最好這樣做)。
我很討厭需要先定義類方法再綁定方法的流程,不過現(xiàn)在可以通過箭頭函數(shù)進(jìn)行自動綁定。箭頭函數(shù)現(xiàn)在可以直接在類中使用。
下面是個例子,其中的_increaseCount被綁定了:
class Counter extends React.Component { constructor(props) { super(props) this.state = { count: 0 } } render() { return() } _increaseCount = () => { this.setState({ count: this.state.count + 1 }) } }{this.state.count}
目前,類屬性不是官方標(biāo)準(zhǔn)的一部分,但是個stage-3的實(shí)驗(yàn)性功能。必須在babelrc中添加@babel/plugin-proposal-class-properties才能使用它。
8. 使用parcel
作為前端開發(fā)者,你肯定會遇到打包和編譯代碼的問題。
長時間以來,實(shí)踐中的標(biāo)準(zhǔn)是webpack。我最初用的是webpack版本1,當(dāng)時用起來很痛苦,需要不斷修改嘗試各種配置選項,我在上面花了無數(shù)個小時想辦法讓它工作。一旦弄好我就絕不會再碰它,以免不小心破壞什么。幾個月之后我遇到了parcel,總算松了口氣。它幾乎可以不加任何配置拿來即用,但你依然可以在需要的時候進(jìn)行改變。它還支持插件,類似于webpack和babel,但非常快。
如果你不知道parcel,我建議你一定要試試。
9. 自己寫更多代碼
這一條很有意思,這個話題我已經(jīng)討論過很多次了。
即使是CSS,許多人也喜歡用現(xiàn)成的庫,比如bootstrap。至于JavaScript,現(xiàn)在還有很多人在用jQuery以及各種小型庫進(jìn)行表單驗(yàn)證、跑馬燈等等。雖然使用庫天經(jīng)地義,但我強(qiáng)烈建議你自己寫更多的代碼,而不是依賴于安裝各種npm包。當(dāng)然,大型的庫(甚至框架)需要整個團(tuán)隊去構(gòu)建,如moment.js或react-dateicker,自己寫是不現(xiàn)實(shí)的。
但是,其他的大部分東西都可以自己寫。這樣能帶來三個好處:
你清楚地知道代碼的內(nèi)容;
在某個點(diǎn)上你開始真正理解編程,知道內(nèi)部的工作原理;
可以防止代碼膨脹。
最初直接使用npm包很方便。自己實(shí)現(xiàn)一些功能會花很多時間。但是,如果安裝的包并不能正常工作,而需要換別的方法,就得花更多的時間去閱讀其API。而在自己實(shí)現(xiàn)時,你可以為項目100%地量身定做。
以上是“JavaScript代碼簡化的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)成都網(wǎng)站設(shè)計公司行業(yè)資訊頻道!
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。