前言
JS的陣列(Array)是我認為最基本且常用的一個物件,所以善用JS提供的Array操作方法就顯得相當重要,過去在使用時每次都要查一下MDN上的Array文件 ,因此這篇就來記錄最常使用的操作方法及過去用錯的地方,希望可以更熟悉來讓程式碼更加簡潔乾淨!
陣列定義
JS中的陣列其實和Java的陣列差不多,兩者都可以當成是由資料所組成的一種資料結構,並且透過索引值(index)來存取裡面的資料,但JS的陣列有幾個特點,分別是:
- JS的陣列也算是一種物件(Object)
- 可存放不同資料型態的元素,且是一個有序的集合
- 可覆寫length屬性來增加移除元素
ES5操作方法
push(element…)
放進push的參數不限數量(一個或多個),並且進一步將參數中的所有值放進陣列的最後一項
1 | let arr = ['a', 'b', 'c', 'd']; |
pop()
這和Java的Stack物件有點像,pop()會返回(return)最後一項的元素,並且在陣列中移除該元素
1 | let arr = ['a', 'b', 'c', 'd']; |
unshift(element…)
功能和push差不多,只是unshift是將參數的元素加入到陣列的第一項
1 | let arr = ['a', 'b', 'c', 'd']; |
shift()
功能和pop差不多,但是針對陣列的第一項元素來操作
1 | let arr = ['a', 'b', 'c', 'd']; |
splice(startIndex, deleteCount, item1…)
splice()是一個來抽換元素很好的方法,第一個參數是必填外,其他都是選填,並且這個方法會返回移除的元素。
- 第一個參數指定要移除並擦入的索引
- 第二個參數則表明是第一個參數後面的幾個元素(有點類似substr(index, length)的length),放空則第一個參數索引後的元素都會被移除,如不想移除就放0就都會保留元素
1
2
3
4
5
6
7let arr = ['a', 'b', 'c', 'd'];
console.log(arr.splice(1)); // ["b","c","d"]
console.log(arr); //["a"]
let arr2 = [1, 2, 3, 4, 5];
console.log(arr2.splice(1, 0)); // []
console.log(arr2); //[1,2,3,4,5] - 第三個參數放置要擦入的元素,一樣是可以不限數量(一個或多個)
1 | let arr = ['a', 'b', 'c', 'd']; |
reverse()
將陣列的元素順序反轉
1 | let arr = ['a', 'b', 'c', 'd']; |
sort(compareFn)
顧名思義就是進行陣列的排序,如果參數放空的話,則會將元素都轉換成字串,並使用第一字元的 Unicode code 來遞增排序,因此,可在sort的參數中傳入一個涵式,其包含兩個參數,兩個參數分別代表陣列中的某一個索引及下一個索引,所以兩者相減為正表示使用遞增排序
- If compareFunction(a, b) returns a value > than 0, sort b before a.
- If compareFunction(a, b) returns a value ≤ 0, leave a and b in the same order.
1 | let arr = [1, 5, 3, 4, 6, 2]; |
copyWithin(target, start, end)
有點類似splice(),但這個方法是用陣列裡面自己的元素來做複製,有三個參數而第一個參數為必填
- 第一個參數為要置換位置的索引
- 第二個參數為要複製的元素起始索引,放空的話預設會從0開始
- 第三個參數為要複製的元素截止索引(不包含自己),放空預設就是陣列長度
1 | let arr = ['a', 'b', 'c', 'd']; |
fill(value, start, end)
有點類似copyWithin,但比較單純就是把value的值置換到從start到end的索引,且一樣也是不包含end自己,然後第一個參數為必填,其他兩個則為選填
1 | let arr = ['a', 'b', 'c', 'd']; |
indexOf(searchElement, fromIndex)
有另外一個類似的方法是lastIndexOf(searchElement, fromIndex),其實就是判斷元素的陣列索引位置,如果陣列沒有此元素則回傳-1
1 | let arr = ['a', 'b', 'c', 'd']; |
ES6操作方法
find(callbackFn)
從陣列中的第一項元素開始放進參數傳入的functoin裡面,來去找出第一個
符合判斷條件的元素,如全部都沒有則返回undefined
1 | let arr = [1, 2, 3, 4, 5, 6]; |
findIndex(callbackFn)
和find其實差不多,只差在findIndex是回傳第一個找到元素的索引位置,沒有符合條件的元素一樣是回傳一個undefined
1 | let arr = [1, 2, 3, 4, 5, 6]; |
filter(callbackFn)
將每一個元素代入callbackFn中,並將符合條件的元素回傳一個新的陣列
1 | let arr = [1, 2, 3, 4, 5, 6]; |
forEach(callbackFn)
過去使用ExtJs裡面就有這種用法,顧名思義就是去迭代這個陣列的元素,針對元素來做一些處理,而callbackFn有三個元素
- 第一個參數為目前迭代元素的值(必填)
- 第二個參數為目前迭代的索引值
- 第三個參數為呼叫該方法的陣列
1
2
3
4
5let arr = [1, 2, 3, 4, 5, 6];
arr.forEach((item, index, array) => {
array[index] = item * 10;
})
console.log(arr); //[10,20,30,40,50,60]
join(separator)
join可以把陣列的元素組合再一起,並且使用參數符號來區隔每一個元素,如果放空預設會用「逗號」來進行合併
1 | let arr = [1, 2, 3, 4, 5, 6]; //console.log(arr.join()); //"1,2,3,4,5,6" |
concat(Array)
concat()可將兩個陣列合併再一起, ES6語法則能夠用擴展運算符…來代替
1 | let arr = [1, 2, 3, 4, 5, 6]; |
slice(start, end)
如同英文字一樣,slice就是把陣列切一段出來,區段一樣也是不包含end自己本身,
類似用途的方法還有 substr() 和 substring()
在使用slice()的時候,如果不給參數,或只給零,那麼slice()就會把陣列從頭到尾複製一份給我們
1 | let arr = [1, 2, 3, 4]; |
map(callbackFn)
map是我在學react時,最常會來使用到的一個方法,他可以針對每一個元素做處理,並回傳一個新的陣列,他的callbackFn和forEach有點類似,有三個元素
- 第一個參數為目前迭代元素的值(必填)
- 第二個參數為目前迭代的索引值
- 第三個參數為呼叫該方法的陣列
1 | let arr = [1, 2, 3, 4, 5]; |
reduce(callbackFn[accumulator, currentValue, currentIndex, array], initialValue)
根據官方定義是The reduce() method executes a reducer function (that you provide) on each member of the array resulting in a single output value.
,所以可以知道reduce會回傳一個值,他的參數可以分成
- accumulator:由 currentValue 加總的累計值
- currentValue:目前迭代的元素值
- currentIndex:目前迭代的索引值
- array:呼叫該方法的陣列
- initialValue:預設值,放在 function 的最後方,非必填
有另外一個相對應的方法reduceRight,更多應用可參考JavaScript reduce 在做什麼? 這篇
1 | let arr = [1, 2, 3, 4, 5]; |
Array.from()
將「類陣列物件」或是「可迭代的物件」轉換成陣列
- 第一個參數為「類陣列物件」或「可迭代的物件」( 必填 )
- 第二個參數為改變轉換成陣列元素的函式,參數分別是(element, index)
其中根據MDN定義array-like objects (objects with a length property and indexed elements); or iterable objects (objects such as Map and Set).
可以知道類陣列物件具有 length 屬性以及索引化 index 的元素,所以會有下面arr3的處理1
2
3
4
5
6
7
8
9
10
11
12
13
14
15let arr = Array.from('KEVIN', e => {
return e + 's'; //[10,20,30,40,50]
});
console.log(arr); //["Ks","Es","Vs","Is","Ns"]
let arr2 = Array.from('KEVIN');
console.log(arr2); // ["K","E","V","I","N"]
let arr = Array.from({length: 5});
console.log(arr); //[undefined,undefined,undefined,undefined,undefined]
let arr = Array.from({length: 5}, (element, index) => {
return index;
});
console.log(arr); //[0,1,2,3,4]
補充
1 | let arr = [1, 2, 3, 4, 5]; |
參考
補充
HTMLCollection 或 NodeList 轉陣列方法
var arr = Array.prototype.slice.call( htmlCollection )
var arr = [].slice.call(htmlCollection);
// es6
var arr = Array.from(htmlCollection);
var arr = […htmlCollection];