趕緊閱讀讀此文,我保證,在過去的幾個月裡我,我確定我在數組問題上犯過4次錯誤。於是我寫下這篇文章,閱讀這篇文章可以讓你更準確的使用javascript數組的一些方法
使用Array.includes替代 Array.indexOf
“如果你在數組中搜尋某個元素,那麼請使用Array.indexOf” ,我記得在學習javascript時看到過這個句子,毫無疑問,這句話很對。
MDN文檔上這樣描述 rray.indexOf“返回第一個被搜尋到的元素的下標(索引)” ,所以如果你想要搜尋某個元素的下標,那麼Array.indexOf可以很好的解決。
但是,如果我們想查看一個數組中是否包涵某個元素該如何做呢。就像yes/no這樣的問題,也就是布爾值。這裡我們推薦使用返回布爾值的Array.includes方法。
const persons = ["jay","leinov","jj","nico"];console.log(persons.indexOf("leinov"));// 1console.log(persons.indexOf("beyond"));// -1 console.log(persons.includes("leinov"));// trueconsole.log(persons.includes("beyond"));// false
使用Array.find代替Array.filter
Array.filter是一個非常有用的方法,它通過一個數組的回調參數建立一個新的數組,正如他的名字所示,我們使用它過濾出一個更短的數組
但是 如果我們明確的知道回呼函數返回的只是數組中的一項,這樣的話我不推薦使用他,例如,當使用的回調參數過濾的是一個唯一的id,這種情況,Array.filter返回一個新的包涵這一項的數組。尋找一個特殊的id,我們目的只想取一項出來,這個返回的數組就是無用的。
接下來我們看下效能,為了返回能夠匹配回呼函數的每一項,Array.filter必須檢索整個數組,此外讓我們想象下,我們有數百個項滿足我們的回調參數函數,我們過濾的數組就非常大了。
為了避免這種情況,我推薦Array.find ,他同Array.filter一樣需要一個回呼函數參數,並且返回第一個能夠滿足回呼函數參數的那一項。並且Array.find 在滿足篩選後停止篩選,不會檢索整個數組。
use strict';const singers = [ { id: 1, name: '周杰倫' }, { id: 2, name: '李建' }, { id: 3, name: '庾澄慶' }, { id: 4, name: '謝霆鋒' }, { id: 5, name: '周杰倫' },];function getSinger(name) { return signer => signer.name === name;}console.log(singers.filter(getSinger('周杰倫')));// [// { id: 1, name: '周杰倫' },// { id: 5, name: '周杰倫' },// ]console.log(characters.find(getSinger('周杰倫')));// { id: 1, name: '周杰倫' }
使用Array.some代替Array.find
我承認經常在這上面犯錯,然後,我的一個好朋友提醒我看下MDN文檔去尋找一個更好的方式解決,這點跟上面的Array.indexOf/Array.includes很相似
在前面提到 Array.find 需要一個回呼函數作為參數來返回一個滿足的元素。如果我們需要知道數組是否包涵某個值時,Array.find是最好的方式嗎。或許不是,因為返回的是一個值,不是一個布爾值。
在這種情況下,我推薦使用Array.some,它返回的是一個是否滿足回調參數的布爾值
'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 and Array.map
讓我們來看看Array.reduce,Array.reduce並不太好理解,但是如果我們執行Array.filter,Array.map感覺我們好像錯過了什麼。
我的意思是,我們檢索了數組兩次,第一次過濾和建立了一個短的數組,第二次建立了一個新的包涵我們過濾擷取到的數組。為了擷取結果我們使用了兩個數組方法,每個方法都有一個回呼函數和一個數組,其中一個Array.filter建立的我們之後是用不到的。
為了避免這個效能的問題,我建議使用Array.reduce來代替。相同的結果,更好的代碼。Aaray.reduce允你篩選和添加滿足的項目到累加器中。例如,這個累加器可以是一個數字增量,一個要填充的對象,一個字串或一個數組。
在我們之前的例子中,我們一直在使用Array.map,所以我建議使用Array.reduce來使用累加器來串連數組。在下面的樣本中,根據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'] }// ]
原文:Here’s how you can make better use of JavaScript arrays
如有哪裡翻譯錯誤請指正 3Q