在JS中,數組是一個非常重要的知識點,不管是在面試還是在日常工作中,都非常需要;而該文章,不去深究數據的定義方法等,而只是總結相應的API並簡單的介紹相應方法的應用;如下圖所示,是我本篇文章介紹的相應的數組方法。
數組的增刪改查
增
arr.push(a,b):在數組arr的最後面增加元素a,b,返回變化後的數組長度
根據定義,可以自己寫一個push方法
arr.unshift(a,b) 在數組arr的首位依次增加a,b;並返回新數組的長度
重寫unshift
改
splice()增加/刪除數組
arr.splice(數組要開始操作的位數,要操作的長度,從操作完最後一位開始增加數據);
其中:如果只填前兩個參數,則會導致數組刪除;而如果有多於兩個參數,同時第二個參數為0的話,就相當於是在要操作的位數開始添加數據。返回值為數組,數組中的值是刪除的參數。如下圖所示:
splice中第一個參數還可以是負數,-1表示最後一位,-2表示倒數第二位,-3表示倒數第三位....
slice(a,b) 將數組內容從下標a到b([a,b)(包括了a,但不包括b))的值複製給一個新數組(a,b如果是負號,則是從右往左開始算起,-1是右起第一個,和splice一樣),並且返回該新數組;如果a,b符號相同的情況下,a的值大於b會導致無法複製出任何值
reverse() 返回一個新數組,新數組與原數組的元素位置首尾顛倒。
concat:連接兩個數組形成一個新數組
變成字符串toString()和join()
toString(),將數組變成字符串,分隔符是逗號,不會變;
join(),將數組變成字符串,分隔符是括號內的值,可以變,默認是逗號;同時如果數組中元素是undefined或者null的話,會被處理位空字符串
另外還有將字符串變成數組的方法split()
arr.split(a,b),a一定是arr的分隔符才行,b代表的是要截取的長度
刪
arr.pop();刪除arr的最後一位,並且返回出去,如果arr是空數組,則返回undefined。
arr.shift()刪除arr的第一位,並且返回出去,如果arr是空數組,則返回undefined。
查
forEach(function(item,index,array){},thisPoint),循環數組的每一項,第一個參數是一個函數,函數有三個默認值,第一個參數是每次循環的元素,第二個參數是循環的該元素的下標,第三個參數是該數組;而第二個參數是改變的this的指向的,如果不填,默認是指向window;返回的是undefined
重寫forEach
filter(function(item,index,array){},thisPoint);和forEach類似,傳入的參數一致,但是其返回是一個數組;同時該數組保存傳入的函數執行後返回值為true的該數組參數,如果函數返回的是false,則返回的是空。即可以作為一個篩選。
其中,有一個bug,即用filter同時數組元素是引用值,會影響到原數組的元素中的值。
重寫filter
map 映射
很多和filter一樣,只是其返回值不同,類型都是數組,但是map中數組的值是函數執行後返回的每個值,即map可以在函數中修改相應的值並返回出去形成一個新數組(會有深拷貝的問題);而filter返回的數組的值是函數執行後返回值為true時該數組的值。
重寫map
reduce/reduceRight遍歷數組
相當於filter和map的優點集合,即可以返回一個篩選好的自定義的值;而不是像filter一樣,只能返回篩選好的只有原數組中有的值,並且不像map一樣返回不能篩選的修改的值。
reduce(function(prev,cur,index,arr){},initialValue,thisPoint);從左往右遍歷數組數據。
其中:
第一個傳入的值是:一個函數,這個函數是有四個參數
prev 上次循環的數據,每次都必須返回出去,作為下次循環的初始值,並且最後返回出去作為最終值。
Cur 本次循環的數據
Index 本次的數據的索引值
Arr 整個data
第二個傳的值是初始值 initialValue,即第一次循環時需要的初始值
第三個傳的值是改變的this指向的。
重寫reduce
reduceRight 和reduce是一個功能,只是其是倒序,是從右往左遍歷數據,而reduce是從左往右遍歷數據
重寫reduceRight
every(function(item,index,array){},thisPoint)遍歷數組,function返回false就終止
some(function(item,index,array){},thisPoint)遍歷數組,function返回true就終止
排序
sort()返回一個數組,該數組默認是按升序將原數組排序,即如果未傳參,則默認按ASCII碼的升序來排列;
如果傳參,就要傳一個函數,該函數有兩個參數a,b,如果該函數的返回值是正數那函數會默認發生改變;
即如果需要按升序排列的話,就需要a<b;而如果需要按降序排序的話,則需要a>b,
ES6
構造器上
Array.of(n) 就是生成數值為n的一個數組[n],Array.of(m,n)是數組[m,n]
解決Array(3) 是[,,,],即三個空元素而不是生成一個元素為3的數組;
Array.from(arraylike,mapFn,thisArg),返回一個數組。
將類數組arraylike轉換成數組,然後執行map方法的函數,thisArg是mapFn函數的this指向(可以達到依賴注入的效果)。
原型上
Arr.fill(value,start,end);start和end是開始索引值,默認是0,end是結束索引值,默認是最後一位;即數組arr從下標start到end用value替換掉,返回的是修改後的數組;
注意
start數大於end數的話,會不做任何處理
該替換的計數是包含start位而不包含end位
負數是從往左算,第一位是-1
如果傳入的參數不合法,變成0,不報錯;
keys()/value()/entries()
數組中的:
Keys() 返回一個包含數組中每個索引鍵的可迭代的Array Iterator對象,不是返回數組
value() 返回一個包含數組中每個索引值的可迭代的Array Iterator對象,不是返回數組
entries()返回一個包含數組中每個索引鍵值對的可迭代的Array Iterator對象,不是返回數組
因為返回是可以迭代的對象,可以用for of的方式進行迭代,也可以用返回值的next方法進行迭代。
注意:對象也有該三個方法,是放在構造器上的;返回的卻是數組,
arr.copyWithin(target,start,end),將該數組的start位開始到end位結束([start,end))的元素複製到該數組的以target位開始的位置,並形成一個新數組返回出去。
findIndex()/indexOf()/includes()
arr.findIndex(function())找到arr中符合function條件的第一個成員的索引,並返回出來,如果沒有則返回-1;與之對應的還有find方法,find是返回相應的元素,沒有則返回undefined;
arr.indexOf(『元素』):判斷數組中是否有該元素,如果有則返回相應的第一個成員的索引,沒有則返回-1;
arr.includes(『元素』):判斷數組中是否有該元素,如果有則返回true,沒有則返回false
如下所示。
當然這三個也有一些特別需要注意的,即NaN 的區別:
indexOf是嚴格的按照 === 來判斷的,即無法判斷NaN的位置,而另外兩種ES6方法則可以找到NaN的位置