JavaScript中Array方法你該知道的正確打開方法
前言
在過去的幾個(gè)月,我發(fā)現(xiàn)我的拉取請(qǐng)求中存在四個(gè)完全相同的 JavaScript 錯(cuò)誤。于是我寫了這篇文章,總結(jié)了如何在 JavaScript 中正確使用地使用 Array 的方法!
Array對(duì)象為JavaScript內(nèi)置對(duì)象,具有以下屬性:
屬性 | 描述 |
---|---|
constructor | 返回對(duì)創(chuàng)建此對(duì)象的數(shù)組函數(shù)的引用。 |
length | 返回?cái)?shù)組中元素的個(gè)數(shù) |
prototype | 向?qū)ο筇砑訉傩院头椒ā?/td> |
用 Array.includes 代替 Array.indexOf
“如果你要在數(shù)組中查找元素,請(qǐng)使用 Array.indexOf”。我記得在學(xué)習(xí) JavaScript 的時(shí)候,在教材中讀到這樣的一句話。毫無疑問,這句話是真的!
MDN 文檔寫道,Array.indexOf 將“返回第一次出現(xiàn)給定元素的索引”。因此,如果我們稍后要在代碼中使用這個(gè)返回的索引,那么使用 Array.indexOf 找到索引就對(duì)了。
但是,如果我們只想知道數(shù)組是否包含某個(gè)值,該怎么辦?這似乎是一個(gè)是與否的問題,或者說是一個(gè)布爾值問題。對(duì)于這種情況,我建議使用返回布爾值的 Array.includes。
'use strict'; const characters = [ 'ironman', 'black_widow', 'hulk', 'captain_america', 'hulk', 'thor', ]; console.log(characters.indexOf('hulk')); // 2 console.log(characters.indexOf('batman')); // -1 console.log(characters.includes('hulk')); // true console.log(characters.includes('batman')); // false
使用 Array.find 而不是 Array.filter
Array.filter 是一個(gè)非常有用的方法。它接受一個(gè)回調(diào)函數(shù)作為參數(shù),基于一個(gè)包含所有元素的數(shù)組創(chuàng)建出一個(gè)新的數(shù)組。正如它的名字一樣,我們使用這個(gè)方法來過濾元素,獲得更短的數(shù)組。
但是,如果回調(diào)函數(shù)只能返回一個(gè)元素,那么我就不推薦使用這個(gè)方法,例如使用回調(diào)函數(shù)來過濾唯一 ID。在這種情況下,Array.filter 將返回一個(gè)只包含一個(gè)元素的新數(shù)組。我們的意圖可能是通過查找特定的 ID 找到數(shù)組中包含的唯一值。
我們來看看這個(gè)方法的性能。要返回與回調(diào)函數(shù)匹配的所有元素,Array.filter 必須遍歷整個(gè)數(shù)組。此外,我們假設(shè)有數(shù)百個(gè)元素可以滿足回調(diào)參數(shù),那么過濾后的數(shù)組會(huì)非常大。
為了避免這種情況,我建議使用 Array.find。它需要一個(gè)像 Array.filter 一樣的回調(diào)函數(shù)作為參數(shù),并返回滿足回調(diào)函數(shù)的第一個(gè)元素的值。此外,只要找到第一個(gè)滿足回調(diào)函數(shù)的元素,Array.find 就會(huì)停止,無需遍歷整個(gè)數(shù)組。通過 Array.find 來查找元素,我們可以更好地理解我們的意圖。
'use strict'; const characters = [ { id: 1, name: 'ironman' }, { id: 2, name: 'black_widow' }, { id: 3, name: 'captain_america' }, { id: 4, name: 'captain_america' }, ]; function getCharacter(name) { return character => character.name === name; } console.log(characters.filter(getCharacter('captain_america'))); // [ // { id: 3, name: 'captain_america' }, // { id: 4, name: 'captain_america' }, // ] console.log(characters.find(getCharacter('captain_america'))); // { id: 3, name: 'captain_america' }
用 Array.some 代替 Array.find
我承認(rèn)這個(gè)錯(cuò)誤我犯了很多次。然后,一位善良的朋友告訴我,最好可以先參考 MDN 文檔。這與上面的 Array.indexOf/Array.includes 非常相似。
在前面的例子中,我們看到 Array.find 需要一個(gè)回調(diào)函數(shù)作為參數(shù),并返回一個(gè)元素。如果我們想要知道數(shù)組是否包含某個(gè)值,Array.find 是最好的解決方案嗎?可能不是,因?yàn)樗祷氐氖且粋€(gè)元素值,而不是一個(gè)布爾值。
對(duì)于這種情況,我建議使用 Array.some,它返回所需的布爾值。另外,從語義上看,Array.some 表示我們只想知道某個(gè)元素是否存在,而不需要得到這個(gè)元素。
'use strict'; const characters = [ { id: 1, name: 'ironman', env: 'marvel' }, { id: 2, name: 'black_widow', env: 'marvel' }, { id: 3, name: 'wonder_woman', env: 'dc_comics' }, ]; function hasCharacterFrom(env) { return character => character.env === env; } console.log(characters.find(hasCharacterFrom('marvel'))); // { id: 1, name: 'ironman', env: 'marvel' } console.log(characters.some(hasCharacterFrom('marvel'))); // true
使用 Array.reduce 而不是鏈接 Array.filter 和 Array.map
讓我們面對(duì)現(xiàn)實(shí)吧,Array.reduce 不容易理解。事實(shí)確實(shí)如此!但是,如果我們使用 Array.filter 和 Array.map 的組合,感覺缺少了什么,對(duì)吧?
我的意思是,我們遍歷了兩次數(shù)組。第一次過濾數(shù)組并創(chuàng)建一個(gè)較短的數(shù)組,第二次又基于 Array.filter 獲得數(shù)組創(chuàng)建一個(gè)包含新值的數(shù)組。為了獲得我們想要的新數(shù)組,我們使用了兩個(gè) Array 方法。每個(gè)方法都有自己的回調(diào)函數(shù)和一個(gè)用不到的數(shù)組——由 Array.filter 創(chuàng)建的那個(gè)數(shù)組。
為了避免這種性能損耗,我的建議是使用 Array.reduce。結(jié)果是一樣的,代碼卻更簡(jiǎn)單! 我們可以使用 Array.reduce 進(jìn)行過濾,并將目標(biāo)元素添加到累加器中。累加器可以是遞增的數(shù)字、要填充的對(duì)象、要連接的字符串或數(shù)組。
在我們的例子中,因?yàn)橹笆褂昧?Array.map,所以我建議使用 Array.reduce 將滿足條件的數(shù)組元素加入到累加器中。在下面的示例中,根據(jù) env 值的具體情況,我們將它添加到累加器中或保持累加器不變。
'use strict'; const characters = [ { name: 'ironman', env: 'marvel' }, { name: 'black_widow', env: 'marvel' }, { name: 'wonder_woman', env: 'dc_comics' }, ]; console.log( characters .filter(character => character.env === 'marvel') .map(character => Object.assign({}, character, { alsoSeenIn: ['Avengers'] })) ); // [ // { name: 'ironman', env: 'marvel', alsoSeenIn: ['Avengers'] }, // { name: 'black_widow', env: 'marvel', alsoSeenIn: ['Avengers'] } // ] console.log( characters .reduce((acc, character) => { return character.env === 'marvel' ? acc.concat(Object.assign({}, character, { alsoSeenIn: ['Avengers'] })) : acc; }, []) ) // [ // { name: 'ironman', env: 'marvel', alsoSeenIn: ['Avengers'] }, // { name: 'black_widow', env: 'marvel', alsoSeenIn: ['Avengers'] } // ]
英文原文:
https://medium.freecodecamp.org/heres-how-you-can-make-better-use-of-javascript-arrays-3efd6395af3c
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
JS動(dòng)態(tài)的把左邊列表添加到右邊的實(shí)現(xiàn)代碼(可上下移動(dòng))
在javascript前端開發(fā)過程中經(jīng)常見到動(dòng)態(tài)的把左邊列表添加到右邊,基于js代碼怎么實(shí)現(xiàn)的呢?今天小編通過本文給大家介紹下js 左邊列表添加到右邊的實(shí)現(xiàn)方法,感興趣的朋友一起看看吧2016-11-11JavaScript實(shí)現(xiàn)循環(huán)輪播圖
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)循環(huán)輪播圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-04-04js純數(shù)字逐一停止顯示效果的實(shí)現(xiàn)代碼
下面小編就為大家?guī)硪黄猨s純數(shù)字逐一停止顯示效果的實(shí)現(xiàn)代碼。小編覺得非常不錯(cuò)?,F(xiàn)在分享給大家。給大家一個(gè)參考2016-03-03用JavaScript對(duì)JSON進(jìn)行模式匹配 (Part 2 - 實(shí)現(xiàn))
在上一篇文章里,我們完成了 Dispatcher 類的接口設(shè)計(jì),現(xiàn)在我們就來考慮一下如何實(shí)現(xiàn)這個(gè)類。2010-07-07