js有很多可以遍歷數組的API,既然已經封裝的這麼好,為什麼不在平常開發的時候使用,本文講講forEach、map、filter、some、every、reduce這些API的使用,並且和普通的for語句作對比。本文主要和大家分享js使用可遍歷陣列的API實例分享,希望能幫助大家。
我們以一個物件陣列作為測試資料:
const testArr = [ { id: 1, name: '张三', age: 18 }, { id: 2, name: '李四', age: 24 }, { id: 3, name: '王小二', age: 22 } ];
列印出所有物件的id,for語句寫法如下:
for (let i = 0, len = testArr.length; i < len; i++) { console.log(testArr[i].id); // 1, 2, 3 }
簡單易懂,接下來看看forEach的寫法:
testArr.forEach(item => console.log(item.id)); // 1, 2, 3
兩者結果是一樣的,for語句是命令式程式設計風格,而forEach是聲明式程式設計風格;前者會告訴機器該如何做,而後者只關注要做什麼。我們推崇後一種寫法,應該盡量使用forEach,這樣我們還不需要寫for()裡面一大串的表達式,何樂而不為。 (ps:如果對效能吹毛求疵的話,還是老老實實用for吧!)
現在我們想得到所有物件的name並組成新的數組,for語句寫法如下:
let names = []; for (let i = 0, len = testArr.length; i < len; i++) { names.push(testArr[i].name); } console.log(names); // [ '张三', '李四', '王小二' ]
比較囉嗦,這種對原數組每個元素進行指定操作並最後返回新數組的問題用map再合適不過了:
testArr.map(item => item.name); // [ '张三', '李四', '王小二' ]
對比for語句,map是多麼優雅啊!
關於map,有個需要注意的點:
[1, 2, 3].map(parseInt); // [ 1, NaN, NaN ]
這裡有些同學會有些疑惑,為什麼結果不是[1, 2, 3]呢?
其實很簡單,map會將三個參數(目前正在遍歷的元素,目前元素索引,原始陣列本身)傳給parseInt,而parseInt是可以有兩個參數的。
這時候就等於執行以下程式碼:
parseInt(1, 0); // 1 parseInt(2, 1); // NaN parseInt(3, 2); // NaN
所以結果為[1, NaN, NaN],而不是[1, 2, 3]。
有時候我們需要篩選出符合指定條件的元素,例如age大於18的對象,for的寫法如下:
let newArr = []; for (let i = 0, len = testArr.length; i < len; i++) { if (testArr[i].age > 18) { newArr.push(testArr[i]); } } console.log(newArr); // [ { id: 2, name: '李四', age: 24 }, { id: 3, name: '王小二', age: 22 } ]
可以看到,寫法很囉嗦,此時用filter的話就很方便了:
testArr.filter(item => item.age > 18); // [ { id: 2, name: '李四', age: 24 }, { id: 3, name: '王小二', age: 22 } ]
filter還可以用於數組去重,程式碼如下:
const arr2 = [1, 2, 4, 1, 3, 2, 6]; arr2.filter((item, idx, arr) => { return arr.indexOf(item) === idx; }); // [ 1, 2, 4, 3, 6 ]
# 取得所有對象的某種屬性,事先需要判斷物件是否具有該屬性,for寫起來有點醜陋:
function getAllOfSomeProps (array, props) { let arr = []; array.forEach((item) => { if (item[props]) { arr.push(item[props]); // => item[props] && arr.push(item[props]) } }) return arr; } getAllOfSomeProps(testArr, 'sex'); // [] getAllOfSomeProps(testArr, 'id'); // [ 1, 2, 3 ] getAllOfSomeProps(testArr, 'name'); // [ '张三', '李四', '王小二' ]
map + filter的組合就優雅的多了:
return array.map(item => item[props]).filter(item => item);
我們再舉個比較通俗的例子,例如我們需要取得陣列裡所有age大於18的物件的name,for語句如下:
let newNames = []; for (let i = 0, len = testArr.length; i < len; i++) { if (testArr[i].age > 18) { newNames.push(testArr[i].name); } } console.log(newNames); // [ '李四', '王小二' ]
再看看map + filter 的寫法:
testArr.filter(item => item.age > 18).map(item => item.name); // [ '李四', '王小二' ]
還是很優雅。
有時候我們需要新增物件但是某些屬性不能重複,for的寫法如下:
function isRepeat (array, props, value) { for (let i = 0, len = array.length; i < len; i++) { if (array[i][props] === value) { return true; } } return false; }
some方法測試陣列中的某些元素是否通過指定函數的測試,改寫如下:
function isRepeat (array, props, value) { return array.some(item => item[props] === value); } isRepeat(testArr, 'name', '张三'); // true isRepeat(testArr, 'name', '李白'); // false
我們需要偵測某個陣列裡的每個物件是否都具有某種屬性,for的寫法如下:
function hasSomeProps (array, props) { for (let i = 0, len = array.length; i < len; i++) { if (!array[i][props]) { return false; } } return true; }
every方法測試陣列的所有元素是否都通過了指定函數的測試。改寫如下:
function hasSomeProps (array, props) { return array.every(item => item[props]); } hasSomeProps(testArr, 'name'); // true
有時需要在滿足某條件下終止循環,例如列印物件訊息,直到name為李四:
for使用break:
for (let i = 0, len = testArr.length; i < len; i++) { if (testArr[i].name === '李四') { break; } console.log(testArr[i]); // { id: 1, name: '张三', age: 18 } }
some,當條件為真時回傳true跳出迴圈:
testArr.some((item) => { if (item.name === '李四') { return true; } console.log(item); // { id: 1, name: '张三', age: 18 } })
every,當條件為真時回傳false跳出迴圈:
testArr.every((item) => { if (item.name === '李四') { return false; } console.log(item); // { id: 1, name: '张三', age: 18 } })
因為forEach是沒有break的,這裡我們可以用some,every替代。
計算[343, 34, 232, 4, 343, 335, 353535]的總和,for的寫法如下:
const arr = [343, 34, 232, 4, 343, 335, 353535]; let sum = 0; for (let i = 0, len = arr.length; i < len; i++) { sum += arr[i]; } console.log(sum); // 354826
使用reduce來做這種累加操作很方便:
arr.reduce((prev, curr) => prev + curr) // 354826
其實不只如此,同學們在平常學習或工作上可以慢慢累積。
總結:遍歷數組的時候應該盡量使用這些API,靈活運用可以讓程式碼更加優雅,這種盡可能使用函數和鍊式呼叫的風格很接近函數式編程,可以提高程式碼品質。
相關推薦:
以上是js使用可遍歷陣列的API實例分享的詳細內容。更多資訊請關注PHP中文網其他相關文章!