趕緊閱讀讀此文,我保證,在過去的幾個月裡我,我確定我在陣列問題上犯過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"));
// 1
console.log(persons.indexOf("beyond"));
// -1
console.log(persons.includes("leinov"));
// true
console.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