最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

談?wù)劄槭裁茨愕?JavaScript 代碼如此冗長

 更新時(shí)間:2019年01月30日 09:20:42   作者:前端大牛愛好者  
這篇文章主要介紹了談?wù)劄槭裁茨愕?JavaScript 代碼如此冗長,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

又一年過去了,JavaScript發(fā)生了許多變化。但是,即使是2019年了,還是需要給一些幫助你編寫干凈、整潔、有效、且具有擴(kuò)展性的代碼建議。

下面是讓你成為更好的開發(fā)者的9條建議。

1. async / await

如果你還在為回調(diào)陷阱煩惱不已,那么就應(yīng)該趕快扔掉這些2014年的代碼了。除非絕對(duì)必要(比如某個(gè)庫要求回調(diào),或者出于性能的原因),否則不要再用回調(diào)了。Promise也不錯(cuò),但當(dāng)代碼規(guī)模越來越大時(shí),它們總是有些別扭。

我的解決方案就是async / await,能讓閱讀代碼變得更容易,代碼變得更整潔。實(shí)際上,Javascript中的任何Promise都可以await,只要你用的庫能返回Promise,就可以await它。實(shí)際上,async/await只不過是promise的語法糖而已。為了讓代碼正確運(yùn)行,你只需在函數(shù)前面加上async即可。

下面是個(gè)例子:

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ù)必要對(duì)代碼進(jìn)行編譯(transpile)。

2. 異步控制流

許多時(shí)候需要獲取多個(gè)數(shù)據(jù)集并在每個(gè)數(shù)據(jù)集上做一些處理,或者在所有異步調(diào)用都返回之后執(zhí)行某項(xiàng)任務(wù)。

for...of

假設(shè)網(wǎng)頁上有一些精靈寶可夢(mèng),我們需要獲取每一只的詳細(xì)信息。我們不能等待所有調(diào)用結(jié)束,因?yàn)槲覀儾恢酪还灿卸嗌僦?。我們希望能在獲取一部分?jǐn)?shù)據(jù)之后立即更新數(shù)據(jù)集,這時(shí)候就可以使用for...of在一個(gè)數(shù)組上進(jìn)行循環(huán),然后在內(nèi)部加入async的代碼塊,但這樣做會(huì)造成阻塞,直到所有調(diào)用結(jié)束。一定要注意,這樣做有可能會(huì)造成性能瓶頸,但這樣做也不失為一種辦法。

例子如下:

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

怎樣才能并行獲取所有寶可夢(mèng)呢?我們可以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è)更簡(jiǎn)單的寫法。我們可以使用解構(gòu)來從一個(gè)數(shù)組或?qū)ο笾蝎@取一個(gè)或多個(gè)值??梢赃@樣寫:

const { data } = await axios.get(...)

這樣就能節(jié)省一行代碼!還可以進(jìn)行重命名:

const { data: newData } = await axios.get(...)

另一個(gè)小技巧就是在解構(gòu)時(shí)制定默認(rèn)值。這樣能保證變量永遠(yuǎn)不會(huì)為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

第一眼看上去這個(gè)例子可能不太容易理解,但多花些時(shí)間研究下是有好處的。當(dāng)我們不給函數(shù)傳遞參數(shù)時(shí),就會(huì)使用默認(rèn)值。如果給函數(shù)傳遞參數(shù),那么不存在的參數(shù)就會(huì)使用默認(rèn)值。

解構(gòu)和默認(rèn)值是在ES6+中引入的,所以代碼需要編譯。

4. 真值和假值

在使用默認(rèn)值時(shí),經(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ù)組
  • 空對(duì)象
  • 任何其他東西

當(dāng)檢查真值或假值時(shí),不需要明確寫出比較,這相當(dāng)于使用雙等號(hào) == 而不是三等號(hào) ===。一般來說,這種用法的行為與預(yù)想是一致的,但有可能會(huì)遇到bug。比如,我最常遇到但就是有關(guān)數(shù)字0的bug。

5. 邏輯運(yùn)算符和三元運(yùn)算符

這些運(yùn)算符也是用來縮減代碼的,節(jié)省下寶貴的代碼行數(shù)。經(jīng)常有許多工具可以保持代碼干凈整潔,但這些工具也會(huì)造成混亂,特別是在改變它們時(shí)。

邏輯運(yùn)算符

邏輯運(yùn)算符可以組合兩個(gè)表達(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)于真值和假值的知識(shí),我們可以將邏輯運(yùn)算符組合起來。在使用邏輯運(yùn)算符時(shí),會(huì)使用以下規(guī)則:

  • && :返回第一個(gè)值為假的表達(dá)式的值。如果不存在,則返回最后一個(gè)值為真的值。
  • || :返回第一個(gè)值為假的表達(dá)式的值。如果不存在,則返回最后一個(gè)值為假的值。
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á)式,但它由三個(gè)部分組成:

  • 比較部分,返回假值或真值;
  • 第一個(gè)值,如果比較為真;
  • 第二個(gè)值,如果比較為假。

下面是例子:

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>

你遇到過這個(gè)問題嗎?在訪問嵌套對(duì)象的屬性時(shí),無法事先確定對(duì)象的屬性是否存在?可能不得不寫這樣的代碼:

let data
if(myObj && myObj.firstProp && myObj.firstProp.secondProp && myObj.firstProp.secondProp.actualData) data = myObj.firstProp.secondProp.actualData

這段代碼很荒謬,我們還有更好的辦法,至少是在建議中的辦法(下面說了怎樣啟用該辦法)。這個(gè)辦法稱為optional chaining,用法如下:

const data = myObj?.firstProp?.secondProp?.actualData

用這個(gè)方法檢查嵌套屬性非常流暢,代碼也能變得更干凈。

目前,optional chaining還不是官方標(biāo)準(zhǔn)的一部分,但它是個(gè)stage-1的實(shí)驗(yàn)性功能。需要在babelrc中加入@babel/plugin-proposal-optional-chaining來啟用它。

7. 類屬性和綁定

JavaScript中的函數(shù)綁定是個(gè)非常常見的任務(wù)。由于ES6標(biāo)準(zhǔn)引入了箭頭函數(shù),我們現(xiàn)在可以自動(dòng)地用定義的形式綁定函數(shù)——這方法非常好用,現(xiàn)在的JavaScript開發(fā)者都在用它。之前類剛剛出現(xiàn)時(shí)是沒辦法使用箭頭函數(shù)的,因?yàn)轭愋枰媚撤N特殊的方式來定義。我們需要在某個(gè)地方進(jìn)行綁定,例如在構(gòu)造函數(shù)里(在React.js中最好這樣做)。

我很討厭需要先定義類方法再綁定方法的流程,不過現(xiàn)在可以通過箭頭函數(shù)進(jìn)行自動(dòng)綁定。箭頭函數(shù)現(xiàn)在可以直接在類中使用。

下面是個(gè)例子,其中的_increaseCount被綁定了:

class Counter extends React.Component {
  constructor(props) {
    super(props)
    this.state = { count: 0 }
  }

  render() {
    return(
      <div>
        <h1>{this.state.count}</h1> 
        <button onClick={this._increaseCount}>Increase Count</button>
      </div>
    )
  }

  _increaseCount = () => {
    this.setState({ count: this.state.count + 1 })
  }
}

目前,類屬性不是官方標(biāo)準(zhǔn)的一部分,但是個(gè)stage-3的實(shí)驗(yàn)性功能。必須在babelrc中添加@babel/plugin-proposal-class-properties才能使用它。

8. 使用parcel

作為前端開發(fā)者,你肯定會(huì)遇到打包和編譯代碼的問題。

長時(shí)間以來,實(shí)踐中的標(biāo)準(zhǔn)是webpack。我最初用的是webpack版本1,當(dāng)時(shí)用起來很痛苦,需要不斷修改嘗試各種配置選項(xiàng),我在上面花了無數(shù)個(gè)小時(shí)想辦法讓它工作。一旦弄好我就絕不會(huì)再碰它,以免不小心破壞什么。幾個(gè)月之后我遇到了parcel,總算松了口氣。它幾乎可以不加任何配置拿來即用,但你依然可以在需要的時(shí)候進(jìn)行改變。它還支持插件,類似于webpack和babel,但非常快。

如果你不知道parcel,我建議你一定要試試。

9. 自己寫更多代碼

這一條很有意思,這個(gè)話題我已經(jīng)討論過很多次了。

即使是CSS,許多人也喜歡用現(xiàn)成的庫,比如bootstrap。至于JavaScript,現(xiàn)在還有很多人在用jQuery以及各種小型庫進(jìn)行表單驗(yàn)證、跑馬燈等等。雖然使用庫天經(jīng)地義,但我強(qiáng)烈建議你自己寫更多的代碼,而不是依賴于安裝各種npm包。當(dāng)然,大型的庫(甚至框架)需要整個(gè)團(tuán)隊(duì)去構(gòu)建,如moment.js或react-dateicker,自己寫是不現(xiàn)實(shí)的。

但是,其他的大部分東西都可以自己寫。這樣能帶來三個(gè)好處:

你清楚地知道代碼的內(nèi)容;

在某個(gè)點(diǎn)上你開始真正理解編程,知道內(nèi)部的工作原理;

可以防止代碼膨脹。

最初直接使用npm包很方便。自己實(shí)現(xiàn)一些功能會(huì)花很多時(shí)間。但是,如果安裝的包并不能正常工作,而需要換別的方法,就得花更多的時(shí)間去閱讀其API。而在自己實(shí)現(xiàn)時(shí),你可以為項(xiàng)目100%地量身定做。

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • layui select 禁止點(diǎn)擊的實(shí)現(xiàn)方法

    layui select 禁止點(diǎn)擊的實(shí)現(xiàn)方法

    今天小編就為大家分享一篇layui select 禁止點(diǎn)擊的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-09-09
  • 工作需要寫的一個(gè)js拖拽組件

    工作需要寫的一個(gè)js拖拽組件

    工作需要寫的一個(gè)js拖拽組件,需要的朋友可以參考下代碼。
    2011-07-07
  • 微信小程序?qū)崿F(xiàn)列表分頁功能

    微信小程序?qū)崿F(xiàn)列表分頁功能

    這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)列表分頁功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • js中符號(hào)轉(zhuǎn)意問題示例探討

    js中符號(hào)轉(zhuǎn)意問題示例探討

    符號(hào)轉(zhuǎn)意,大家或許有所了解,知識(shí)在使用中或許不是那么的在意,其實(shí)這個(gè)問題很重要,下面為大家講解下js符號(hào)轉(zhuǎn)意問題相關(guān)知識(shí),感興趣的朋友可以參考下
    2013-08-08
  • js尾調(diào)用優(yōu)化的實(shí)現(xiàn)

    js尾調(diào)用優(yōu)化的實(shí)現(xiàn)

    這篇文章主要介紹了js尾調(diào)用優(yōu)化的實(shí)現(xiàn),尾調(diào)用(Tail Call)是函數(shù)式編程的一個(gè)重要概念,本文介紹它的含義和用法。感興趣的可以了解一下
    2019-05-05
  • javascript 變態(tài)的節(jié)點(diǎn)集合

    javascript 變態(tài)的節(jié)點(diǎn)集合

    今天想實(shí)現(xiàn)jQuery的unwrap效果,換言之,就是用其孩子把其父節(jié)點(diǎn)干掉。為了效率,用到文檔碎片,而取孩子時(shí)使用到childNodes(返回一個(gè)nodeList)
    2010-03-03
  • JS apply用法總結(jié)和使用場(chǎng)景實(shí)例分析

    JS apply用法總結(jié)和使用場(chǎng)景實(shí)例分析

    這篇文章主要介紹了JS apply用法總結(jié)和使用場(chǎng)景,結(jié)合實(shí)例形式分析了JS apply的基本功能、原理、使用方法及操作注意事項(xiàng),需要的朋友可以參考下
    2020-03-03
  • JS遍歷頁面所有對(duì)象屬性及實(shí)現(xiàn)方法

    JS遍歷頁面所有對(duì)象屬性及實(shí)現(xiàn)方法

    下面小編就為大家?guī)硪黄狫S遍歷頁面所有對(duì)象屬性及實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-08-08
  • javascript實(shí)現(xiàn)簡(jiǎn)單的on事件綁定

    javascript實(shí)現(xiàn)簡(jiǎn)單的on事件綁定

    這篇文章主要介紹了javascript中Event 對(duì)象中的 on, off 方法,非常的簡(jiǎn)單實(shí)用,有需要的小伙伴可以參考下
    2016-08-08
  • JavaScript其他類型的值轉(zhuǎn)換為布爾值的規(guī)則詳解

    JavaScript其他類型的值轉(zhuǎn)換為布爾值的規(guī)則詳解

    在JavaScript中,所有的值在邏輯上下文中都會(huì)被轉(zhuǎn)換為布爾類型(Boolean),理解這些轉(zhuǎn)換規(guī)則對(duì)開發(fā)者來說至關(guān)重要,尤其是在條件判斷、短路運(yùn)算、邏輯非(!)等場(chǎng)景下,正確掌握布爾轉(zhuǎn)換可以避免潛在的bug,本文將詳細(xì)介紹 JavaScript 其他類型的值是如何轉(zhuǎn)換為布爾值的
    2025-04-04

最新評(píng)論

黑水县| 四平市| 象州县| 长岭县| 商南县| 东台市| 靖宇县| 裕民县| 江华| 五峰| 武定县| 余庆县| 浦江县| 清苑县| 琼海市| 盐池县| 蒙山县| 闻喜县| 长沙市| 托里县| 盐山县| 鄄城县| 名山县| 库尔勒市| 两当县| 郧西县| 玉门市| 望江县| 阿坝| 哈尔滨市| 太保市| 奉贤区| 徐汇区| 高安市| 安顺市| 宁明县| 靖远县| 襄垣县| 财经| 绵阳市| 承德市|