大家好,我是若川。最近組織了源碼共讀活動,感興趣的可以點此加我微信 ruochuan12?參與,每周大家一起學習200行左右的源碼,共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》?包含20余篇源碼文章。
? ? 我們在日常開發中,與接口打交道最多了,前端通過訪問后端接口,然后將接口數據二次處理渲染到頁面當中。
? ? 二次處理的過程是 考驗 ?Coder
對 Array
是否熟練 以及 在 何種 場景下使用哪種方法處理最優 。
? ? 小編,在最近開發中就遇到了 Array
問題, 在處理復雜的業務需求時,沒想到Array
有類似的方法,然后將方法 組合起來解決當下問題。
文章用下班時間肝了一周才寫完。
數組使用指南
遍歷數組方法
不會改變原數組的遍歷方法
forEach()
forEach()
方法按照升序為數組中每一項執行一次給定的函數。
「語法」
arr.forEach(callback(currentValue?,?index?,?array)?,thisArg)
currentValue
: ?數組當前項值index
: ?數組當前項索引arr
: 數組對象本身thisArg
: 可選參數。當執行回調函數callback
時,用作this
的值。
「注意」
如果使用 「箭頭函數表達式」來傳入函數參數,
thisArg
參數會被忽略,因為箭頭函數在詞法上綁定了this
值。forEach
不會直接改變調用它的對象,但是那個對象可能會被callback
函數改變。every
不會改變原數組。
//防盜貼:微信公眾號:?前端自學社區const?arr?=?[2,3,4,1,44]arr.forEach(val?=>{console.log(`值為${val*2}`)})
console.log(`原數組為${arr}`);
//?值為4
//?值為6
//?值為8
//?值為2
//?值為88
//?原數組為2,3,4,1,44
reduce()
reduce()
數組元素累計器,返回一個合并的結果值。
「語法」
arr.reduce(callback(accumulator,?currentValue,?index,?array),?initialValue)
accumulator
: ?累計器,默認為數組元素第一個值currentValue
: ?當前值index
: 當前元素索引 可選array
: 數組 可選initialValue
: 初始值 ?可選
reduce
有兩個參數,一個是回調函數,一個是初始值。
它有兩種取值情況:
當提供了
initialValue
初始值時, 那么accumulator
的值為initialValue
,currentValue
的值為數組第一個值
當沒有提供
initialValue
初始值時, 那么accumulator
的值 為 數組第一個值,currentValue
為第二個值。
「注意」
如果數組為空,且沒有提供
initialValue
初始值時,會拋出TypeError
.如果數組有一個元素,且沒有提供
initialValue
或者 ?提供了initialValue
,數組為空,那么唯一值被返回不會執行callback
回調函數。
「求和」
//防盜貼:微信公眾號:?前端自學社區/
const?arr?=?[1,?2,?3,?4]const?sum?=?arr.reduce((accumulator,?currentValue)?=>?accumulator?+?currentValue,?10)console.log(sum)?//20?
//?accumulator??累計器
//?currentValue??當前值
//?initialValue??累計?初始值?為10?//10?+?1?+?2?+?3?+?4##?注意
//?回調函數第一次執行時,accumulator 和currentValue的取值有兩種情況:
//?如果調用reduce()時提供了initialValue,accumulator取值為initialValue,currentValue取數組中的第一個值;
//?如果沒有提供 initialValue,那么accumulator取數組中的第一個值,currentValue取數組中的第二個值。
「計算對象中的值」
要累加對象數組中包含的值,必須提供初始值,以便各個item正確通過你的函數。
/**?@Description:?*?@Author:?微信公眾號:?前端自學社區*?@Date:?2021-08-07?00:53:51*?@LastEditTime:?2021-08-07?00:53:51*?@LastEditors:?Do?not?edit*/
const?data?=?[{date:?'2021-8-1',income:?200},{date:?'2021-8-2',income:?400},{date:?'2021-8-3',income:?300},
]console.log(`總收入:?${data.reduce(?(pre,currentValue)?=>?pre?+?currentValue.income,0)}`);
//總收入:900
「二維數組轉一位數組」
const?array?=?[[1,2],[3,4]]console.log(array.reduce((a,b)?=>?a.concat(b)));
//[?1,?2,?3,?4?]
find()
find()
返回滿足特定條件的元素對象或者元素值, 不滿足返回 undefined
「語法」
arr.find((element,index,array),?thisArg)
element
:當前元素index
: ? 當前元素索引 可選array
: ?數組本身 可選thisArg
: 執行回調時用作this
的對象。可選
//?從數據中找出第一個滿足特定條件的對象const?data?=?[{name:'張三',article:?3},{name:'老王',article:?9},{name:'老李',article:?10}
]console.log(data.find(item?=>?item.article?>?9?));//?{?name:?'老李',?article:?10?}
findIndex()
findIndex()
返回數組中符合條件的第一個元素的索引,沒有,則返回 ?-1
。
「語法」
arr.findIndex((element,index,array),?thisArg)
element
:當前元素index
: ? 當前元素索引 可選array
: ?數組本身 可選thisArg
: 執行回調時用作this
的對象。可選
const?arr?=?[22,33,44,55]
console.log(arr.findIndex(val?=>?val?>?33));????//2
console.log(arr.findIndex(val?=>?val?>?99));????//-1
key()
key()
返回一個新的「Array Iterator」對象,該對象包含數組中每個索引的鍵。
「語法」
keys()
「注意」
如果數組中有空原元素,在獲取key 時, 也會加入遍歷的隊列中。
const?inputModal?=?[{name:''},{age:''},{hobby:''}
]
for(const?key?of?inputModal.keys()){console.log(key)
}
//?0
//?1
//?2const?arr?=?[1,2,,3]
for(const?key?of?arr.keys()){console.log(key);
}
//?0
//?1
//?2
//?3//Object.keys()?方法會返回一個由一個給定對象的自身可枚舉屬性組成的數組
//?所以?Object.keys(arr)?=?[?'0',?'1',?'3'?]
for(const?key?of?Object.keys(arr)){console.log(key);
}
//?0
//?1
//?3
values()
values()
方法返回一個新的 「Array Iterator」 對象,該對象包含數組每個索引的值。
「語法」
arr.values()
const?Color?=?['red','yelloe','orange']for(val?of?Color.values()){console.log(val);
}
//?red
//?yelloe
//?orange
返回 布爾值
every()
every
用來判斷數組內所有元素是否符合某個條件,返回 「布爾值」
「語法」
arr.every(callback(currentValue?,?index?,?array)?,thisArg)
currentValue
: ?數組當前項值 ? 必須index
: ?數組當前項索引 ? 可選arr
: 數組對象本身可選thisArg
: 可選參數。當執行回調函數callback
時,用作this
的值。可選
「注意」
當所有的元素都符合條件才會返回
true
every
不會改變原數組。若傳入一個空數組,無論如何都會返回
true
。
//防盜貼:微信公眾號:?前端自學社區const?arr?=?[2,3,4,1,44]console.log(arr.every(val?=>??val?>?0?));???//trueconsole.log(arr.every(val?=>?{?val?>?2?}))?//false
some()
some()
用來判斷數組元素是否符合某個條件,只要有一個元素符合,那么返回 true
.
「語法」
arr.some(callback(currentValue?,?index?,?array)?,thisArg)
currentValue
: ?數組當前項值 ? 必須index
: ?數組當前項索引 ? 可選arr
: 數組對象本身可選thisArg
: 可選參數。當執行回調函數callback
時,用作this
的值。可選
「注意」
some()
被調用時不會改變數組。如果用一個空數組進行測試,在任何情況下它返回的都是
false
。some()
在遍歷時,元素范圍已經確定,在遍歷過程中添加的元素,不會加入到遍歷的序列中。
const?arr?=?[2,3,4,1,44]console.log(arr.some(val?=>?val?>?2))??//true
console.log([].some(val?=>?val?>?2?));?//falseconst?newList?=?[11,22,33,44]
console.log(newList.some(val?=>?{newList.push(55)newList.push(66)val?>?55
}));???//false
不改變原有數組,形成新的數組
filter()
filter()
用來遍歷原數組,過濾拿到符合條件的數組元素,形成新的數組元素。
「語法」
arr.some(callback(currentValue?,?index?,?array)?,thisArg)
currentValue
: ?數組當前項值 ? 必須index
: ?數組當前項索引 ? 可選arr
: 數組對象本身可選thisArg
: 可選參數。當執行回調函數callback
時,用作this
的值。可選
「注意」
filter
不會改變原數組,它返回過濾后的新數組。filter()
在遍歷時,元素范圍已經確定,在遍歷過程中添加的元素,不會加入到遍歷的序列中。
const?arr?=?[11,22,33,44,55,66]console.log(arr.filter(val?=>?val?>?44?))
console.log(`原數組為${arr}`);//?[?55,?66?]
//?原數組為11,22,33,44,55,66
map()
map()
創建一個新的數組,其結果是該數組中的每個元素都調用一個提供的函數后返回的結果。
「語法」
arr.map(callback(currentValue?,?index?,?array)?,thisArg)
currentValue
: ?數組當前項值 ? 必須index
: ?數組當前項索引 ? 可選arr
: 數組對象本身可選thisArg
: 可選參數。當執行回調函數callback
時,用作this
的值。可選
「注意」
map
不修改調用它的原數組本身map()
在遍歷時,元素范圍已經確定,在遍歷過程中添加的元素,不會加入到遍歷的序列中。
const?arr?=?[1,2,3,4]console.log(arr.map(val?=>?val*3?))??//?[?3,?6,?9,?12?]
console.log(arr)??//?[?1,?2,?3,?4?]
數組 CRUD
改變原數組方法
reverse()
reverse()
方法將數組中元素的位置顛倒,并返回該數組。數組的第一個元素會變成最后一個,數組的最后一個元素變成第一個。該方法會改變原數組。
const?arr?=?[1,2,3]console.log(arr.reverse(11,22,33))??//[?3,?2,?1?]
sort()
sort()
方法采用 「原地算法」進行排序并返回數組。默認排序順序是在「將元素轉換為字符串」,然后「比較它們的UTF-16
代碼單元值序列」
「原地算法」是一個使用輔助的數據結構對輸入進行轉換的算法。但是,它允許有少量額外的存儲空間來儲存輔助變量。當算法運行時,輸入通常會被輸出覆蓋。原地算法僅通過替換或交換元素來更新輸入序列。
const?arr?=?[23,11,33,44,1]console.log(arr.sort())??//[?1,?11,?23,?33,?44?]const?arr?=?[23,11,33,44,1000000000]console.log(arr.sort())??
//?[?1000000000,?11,?23,?33,?44?]
刪除元素
shift()
shift()
方法從數組中刪除「第一個」元素,并返回該元素的值。此方法更改數組的長度。
「語法」
arr.shift()
「注意」
從數組中刪除的元素; 如果數組為空則返回
undefined
const?data?=?[{id:1,name:'前端'},{id:2,name:'后端'},{id:3,name:'移動端'},{id:4,name:'嵌入式開發'},
]const?deleObj?=?data.shift()console.log('==============刪除后的元素======================');
console.log(data);
console.log('=================刪除后的元素===================');console.log('===============被刪除的元素=====================');
console.log(deleObj);
console.log('================被刪除的元素====================');//??==============刪除后的元素======================
//?[
//?????{?id:?2,?name:?'后端'?},
//?????{?id:?3,?name:?'移動端'?},
//?????{?id:?4,?name:?'嵌入式開發'?}
//???]
//???=================刪除后的元素===================//???===============被刪除的元素=====================
//???{?id:?1,?name:?'前端'?}
//???================被刪除的元素====================
pop()
pop()
方法從數組中刪除最后一個元素,并返回該元素的值。此方法更改數組的長度。
用法和 shift
類似。
「語法」
arr.pop()
「注意」
從數組中刪除的元素; 如果數組為空則返回
undefined
const?data?=?[{id:1,name:'前端'},{id:2,name:'后端'},{id:3,name:'移動端'},{id:4,name:'嵌入式開發'},
]const?deleObj?=?data.pop()console.log(data);
//?[
//?????{?id:?1,?name:?'前端'?},
//?????{?id:?2,?name:?'后端'?},
//?????{?id:?3,?name:?'移動端'?}
//?]
console.log(deleObj);
//?{?id:?4,?name:?'嵌入式開發'?}
splice()
splice()
方法通過「刪除」或「替換」現有元素或者原地添加新的元素來修改數組,并以數組形式返回被修改的內容。此方法會改變原數組。
「語法」
array.splice(start,deleteCount,?[item1,item2....])
start
: 開始的索引deleteCount
: 刪除的個數 ?可選[item1,item2 .....]
;從開始的索引進行 添加的增加和替換的元素, 可選
「注意」
由被刪除的元素組成的一個數組。如果只刪除了一個元素,則返回只包含一個元素的數組。如果沒有刪除元素,則返回空數組。
如果只傳遞了開始的索引位置,則會刪除索引后的所有元素對象
const?data?=?[{id:1,name:'前端'},{id:2,name:'后端'},{id:3,name:'移動端'},{id:4,name:'嵌入式開發'}, ] data.splice(1) console.log(data) //?[?{?id:?1,?name:?'前端'?}?]
「從索引為 2 開始, 刪除 1 個數組元素對象,添加兩個數組元素對象」
const?data?=?[{id:1,name:'前端'},{id:2,name:'后端'},{id:3,name:'移動端'},{id:4,name:'嵌入式開發'},
]data.splice(2,1,...[{id:5,name:'人工智能'},{id:6,name:'大數據開發'}])console.log(data);
//?[
//?????{?id:?1,?name:?'前端'?},
//?????{?id:?2,?name:?'后端'?},
//?????{?id:?5,?name:?'人工智能'?},
//?????{?id:?6,?name:?'大數據開發'?},
//?????{?id:?4,?name:?'嵌入式開發'?}
//?]
增加元素
splice()
上面已經有介紹
push()
push()
方法將一個或多個元素添加到數組的「末尾」,并返回該數組的新長度。
「語法」
arr.push(element1,?...,?elementN)
const?data?=?[{id:1,name:'前端'},{id:2,name:'后端'},
]console.log(data.push({id:3,name:'移動端'}))??//3
「合并數組」
const?data?=?[{id:1,name:'前端'},{id:2,name:'后端'},
]var?obj?=?[{id:4,name:'嵌入式開發'},
]//?相當于?data.push({id:4,name:'嵌入式開發'});
Array.prototype.push.apply(data,?obj);console.log(data);[{?id:?1,?name:?'前端'?},{?id:?2,?name:?'后端'?},{?id:?4,?name:?'嵌入式開發'?}
]
unshift()
unshift()
方法將一個或多個元素添加到數組的「開頭」,并返回該數組的「新長度」。
const?arr?=?[1,2,3]console.log(arr.unshift(11,22,33))??//6?
console.log(arr)??//[?11,?22,?33,?1,?2,?3?]
不改變原數組元素方法
indexOf()
indexOf()
方法返回可以在數組中找到給定元素的第一個索引,如果不存在,則返回 -1。
「語法」
indexOf(searchElement)
indexOf(searchElement,?fromIndex)
searchElement
: ? 要查找的元素fromIndex
:?按指定的索引進行查找出現的指定元素的第一個索引。?可選??
如果索引大于或等于數組的長度,則返回-1
如果提供的索引值為負數,則將其視為距數組末尾的偏移量
如果提供的索引為負數,仍然從前到后搜索數組
如果提供的索引為 0,則將搜索整個數組。
默認值:0(搜索整個數組)。
const?arr?=?[1,1,2,3,4,5,4,4,6]console.log(arr.indexOf(3));??//3
console.log(arr.indexOf(9));??//-1console.log(arr.indexOf(3,4));?//-1
//從索引為?4?的元素進行查找?3,?顯然后面沒有3?,?返回?-1
「數組去重」
創建一個新的空數組,通過indexOf
來判斷空數組是否第一次存在某個元素,
不存在則返回 [ ?< 0 ? ] ,
push
到空數組中.
const?newArr?=?[]
arr.forEach(val?=>?{if(newArr.indexOf(val)?<?0){newArr.push(val)}
})
console.log(newArr);
//?[?1,?2,?3,?4,?5,?6?]
lastIndexOf()
lastIndexOf()
查找數組中元素最后一次出現的索引,如未找到返回-1。
如果不存在則返回 -1。從數組的后面向前查找,從 fromIndex
處開始。
「語法」
arr.lastIndexOf(searchElement,?fromIndex)
searchElement
: ? 要查找的元素fromIndex
:?按指定的索引進行查找出現的指定元素的第一個索引。?可選??
從指定的索引位置 「逆向」 查找
默認為數組的長度減 1(
arr.length - 1
),即整個數組都被查找。如果該值大于或等于數組的長度,則整個數組會被查找。
如果為負值,數組仍然會被從后向前查找。
如果該值為負時,其絕對值大于數組長度,則方法返回 -1,即數組不會被查找。
「注意」
lastIndexOf
使用的是 「嚴格相等」 ? === ?比較 ?searchElement
和數組中的元素。
const?arr?=?[1,1,2,3,4,5,4,4,6]console.log(arr.lastIndexOf(4));?//7console.log(arr.lastIndexOf(4,11));??
//7????指定的查找的索引?大于?數組的長度,?會進行整個數組查找console.log(arr.lastIndexOf(4,-33));
//?-1???指定的索引為負數,且絕對值大于數組長度,?則返回?-1console.log(arr.lastIndexOf(4,-5));
//4????指定的索引為負數,且絕對值小于數組長度,?則會?從向前進行查找
inCludes()
includes()
方法用來判斷一個數組是否包含一個指定的值,根據情況,如果包含則返回 true,否則返回false。
「語法」
arr.includes(searchElement,?fromIndex)
searchElement
: ? 要查找的元素?
查找時,區分大小寫
?fromIndex
:?按指定的索引進行查找出現的指定元素的第一個索引。?可選??
從指定的索引進行查找
如果為負值,則按升序從
array.length + fromIndex
的索引開始搜如果
fromIndex
大于等于數組的長度,則會返回false
,且該數組不會被搜索。默認為0
const?arr?=?[1,1,2,3,4,5,4,4,6]console.log(arr.includes(4));?//trueconsole.log(arr.includes(4,66));?//falseconsole.log(arr.includes(1,-1));?//false
concat()
concat()
方法用于合并兩個或多個數組。
「語法」
var?new_array?=?old_array.concat([arr1][arr2])
「注意」
concat
方法不會改變this
或任何作為參數提供的數組,而是返回一個「淺拷貝」,它包含與原始數組相結合的相同元素的副本??
對象引用(而不是實際對象):
concat
將對象引用復制到新數組中。原始數組和新數組都引用相同的對象。也就是說,如果引用的對象被修改,則更改對于新數組和原始數組都是可見的。這包括也是數組的數組參數的元素。數據類型如字符串,數字和布爾(不是
String
,Number
和Boolean
) 對象):concat
將字符串和數字的值復制到新數組中。
let?arr1?=?[1,2,3]
let?arr2?=?[4,5,6]
let?arr3?=?[[1,2],[3,4]]
console.log(arr1.concat(arr2));
//[?1,?2,?3,?4,?5,?6?]//?嵌套合并
console.log(arr1.concat(arr2).concat(arr3));
//?[?1,?2,?3,?4,?5,?6,?[?1,?2?],?[?3,?4?]?]let?obj1?=?[{a:1},{b:2}]
let?obj2?=?[{c:3},{d:4}]
let?obj3?=?obj1.concat(obj2)??
console.log(obj3);?
//[?{?a:?1?},?{?b:?2?},?{?c:?3?},?{?d:?4?}?]obj1[0].a?=?4??//改變obj[0]對象值,會直接影響合并后的數組,因為是淺拷貝
console.log(obj3);?
//[?{?a:?4?},?{?b:?2?},?{?c:?3?},?{?d:?4?}?]
toString()
toString()
返回一個字符串,表示指定的數組及其元素。
「當一個數組被作為文本值或者進行字符串連接操作時,將會自動調用其 toString
方法。」
對于數組對象,toString
方法連接數組并返回一個字符串,其中包含用逗號分隔的每個數組元素。
「語法」
arr.toString()
const?arr?=?[1,2,3]console.log(arr.toString());??//1,2,3
join()
join()
方法通過連接數組元素用逗號或指定的分隔符字符串分隔,返回一個字符串。
如果數組只有一項,則將在不使用分隔符的情況下返回該項。
「語法」
join()
join(separator)
separator
: ?指定的分割的 字符 ?可選
const?arr?=?['2021','08','08']console.log(arr.join());?????//2021,08,08
console.log(arr.join('-'));??//2021-08-08
console.log(arr.join('/'));??//2021/08/08
slice()
slice()
方法返回一個新的數組對象,這一對象是一個由 begin
和 end
決定的原數組的「淺拷貝」(包括 begin
,不包括end
)。原始數組不會被改變。
「語法」
arr.slice(begin,?end)
begin
: 指定截取的「開始」索引 ?可選??
默認從0 開始
如果
begin
為負數,則以數組末尾開始 的 絕對值開始截取 ?slice(-2)
?末尾第2個元素如果
begin
超出原數組的索引范圍,則會返回空數組。
end
: 指定截取的「結束」索引 ? ?可選??
如果
end
被省略,則slice
會一直提取到原數組末尾。如果
end
大于數組的長度,slice
也會一直提取到原數組末尾。如果
end
為負數, 則它表示在原數組中的倒數第幾個元素結束抽取。
const?arr?=?[11,22,33,44,55,66,77,88]console.log(arr.slice(1,4));
//?應該返回?索引?1?-?3?的數組元素
//?[?22,?33,?44?]console.log(arr.slice(-4,2))??//[]console.log(arr.slice(-4));???//[?55,?66,?77,?88?]console.log(arr.slice(0,-1));
//?[
//?????11,?22,?33,?44,
//?????55,?66,?77
//???]
參考文獻
Array - JavaScript | MDN
·················?若川簡介?·················
你好,我是若川,畢業于江西高校。現在是一名前端開發“工程師”。寫有《學習源碼整體架構系列》20余篇,在知乎、掘金收獲超百萬閱讀。
從2014年起,每年都會寫一篇年度總結,已經寫了7篇,點擊查看年度總結。
同時,最近組織了源碼共讀活動,幫助3000+前端人學會看源碼。公眾號愿景:幫助5年內前端人走向前列。
識別上方二維碼加我微信、拉你進源碼共讀群
今日話題
略。分享、收藏、點贊、在看我的文章就是對我最大的支持~