JavaScript數組方法總結

gidi521 7年前發布 | 10K 次閱讀 JavaScript開發 JavaScript

說起來很搞笑,我在用 sublime 3 寫排序算法的時候,準備用 nodejs 來運行,就用 sublime 3 提供的編譯功能。但問題來了,我比較挫,寫了個死循環,然后 sublime 3 也不給輸出提示,我很疑惑的連續跑了 3 遍,過了一會電腦發熱,風扇開始叫了,我察覺到,一看進程,3 個 node 進程在狂吃內存和 cpu,我在想,這個 bug 該反饋給 sublime 3 還是 node 呢?

JavaScript 中的數組本身就很特別,不像 C 或 Java,搞了數組、list 一整套東西,JS 中的數組就完全可以當作一個棧或隊列來使用,四大操作 pop、push、shift、unshift。

我今天寫這篇博客,主要是寫一篇總結,以備以后查看,因為我發現無論數組操作多熟,時間久了都會忘記。

對于一個數組方法,我最關心的有兩個問題, 返回值是什么,會不會對原始數組造成影響 ,典型的例子就是 splice 和 slice 方法。對于那些返回原數組的函數,我們可以直接調用數組的鏈式調用,很酷( array.filter().sort().reverse() )。

我想帶著這兩個疑問,來總結下 Array 的數組方法。

Array

Array.length 是數組的長度,每個新建的數組對象都會有 length 對象,可以通過 Array.prototype 修改原型,不過數組的基本使用和操作不是今天的重點,我們來看數組方法。

一般情況下,數組方法在最后都會帶有一個 thisArg 的參數,這個參數會指定內部 this 的指向。如果參數中有回掉函數,這個回掉函數一般接受 3 個參數,value、index 和 array,分別代表當前傳入的值,當前傳入值所在的索引和當前的處理的數組。

目錄索引:

concat

這個方法可以用于數組的拼接,參數是一個或多個數組,返回的結果是拼接數組。 

concat 方法將創建一個新數組,然后將調用它的對象(this 指向的對象,即原數組)中的元素以及所有參數中的數組類型的參數中的元素以及非數組類型的參數本身按照順序放入這個新數組,并返回該數組。concat 方法并不修改原數組和參數數組,而且對非數組對象同樣有效果。

  1. 返回拼接的新數組;
  2. 不修改原數組和參數數組;
  3. 參數可以是非數組。
var a1 = [1, 2, 3],
  a2 = [4, 5, 6],
  a3 = [7, 8, 9];
var newarr = a1.concat(a2, a3);
newarr //[1, 2, 3, 4, 5, 6, 7, 8, 9]
a1 //[1, 2, 3]
newarr = a1.concat(4, a3);//[1, 2, 3, 4, 7, 8, 9]
newarr = a1.concat('hello');//[1, 2, 3, "hello"]

every

every() 方法測試數組的所有元素是否都通過了指定函數的測試。 

arr.every(callback) 會對每一個元素都執行 callback 方法,直到 callback 返回 false。有時候 every 方法會和 forEach 方法相比較,因為 forEach 無法停止,而 every 方法返回 flase 時可以中途停止。

  1. 若全部通過測試,函數返回值 true,中途退出,返回 false;
  2. 不對原數組產生影響。
function isBigEnough(element, index, array) {
  console.log(index);
  return (element >= 10);
}
var passed = [12, 5, 8, 130, 44].every(isBigEnough);
// 0
// 1
// passed is false
passed = [12, 54, 18, 130, 44].every(isBigEnough);
// 0 1 2 3 4
// passed is true

filter

filter() 方法使用指定的函數測試所有元素,并創建一個包含所有通過測試的元素的新數組。

其實這個方法就是一個過濾方法,前面那個 every 方法,只判斷不過濾,filter 會過濾掉一些不符合條件的,并返回新數組。

  1. 返回一個滿足過濾條件的新數組;
  2. 不會改變原數組。
function isBigEnough(element, index, array) {
  return (element >= 10);
}
var a1 = [19, 22, 6, 2, 44];
var a2 = a1.filter(isBigEnough);
a1 //[19, 22, 6, 2, 44]
a2 //[19, 22, 44]

forEach

forEach() 方法對數組的每個元素執行一次提供的函數(回調函數)。 

  1. 函數沒有返回值,即 underfined;
  2. 不對原數組產生影響。
function logArrayElements(element, index, array) {
    console.log("a[" + index + "] = " + element);
}

// 注意索引2被跳過了,因為在數組的這個位置沒有項
var result = [2, 5, 9].forEach(logArrayElements);
// a[0] = 2
// a[1] = 5
// a[2] = 9
result //underfined

indexOf

indexOf()方法返回給定元素能找在數組中找到的第一個索引值,否則返回-1。

  1. 返回值是找到元素的索引值或 -1;
  2. 不對原數組產生影響。
var array = [1, 2, 5];
array.indexOf(5); // 2
array.indexOf(7); // -1

join

join() 方法將數組中的所有元素連接成一個字符串。

其實,對于 join 想到的第一個是字符串的 split 操作,這兩個經常搭配用來處理字符串。

  1. 返回拼接的字符串;
  2. 不對原數組產生影響。
var a1 = [1, 2, 3];
var a2 = a1.join();
a1 //[1, 2, 3]
a2 //"1,2,3"
a2 = a1.join("");//"123"
a2 = a1.join("-");//"1-2-3"

lastIndexOf

lastIndexOf() 方法返回指定元素(也即有效的 JavaScript 值或變量)在數組中的最后一個的索引,如果不存在則返回 -1。從數組的后面向前查找,從 fromIndex 處開始。 

其實這個就是 indexOf 的翻版。

  1. 返回找到的第一個元素的索引;
  2. 不對原數組產生影響。
var array = [2, 5, 9, 2];
var index = array.lastIndexOf(2);
// index is 3
index = array.lastIndexOf(7);
// index is -1
index = array.lastIndexOf(2, 3);
// index is 3
index = array.lastIndexOf(2, 2);

map

map() 方法返回一個由原數組中的每個元素調用一個指定方法后的返回值組成的新數組。 

map reduce 這兩個函數在處理數組上一直都是一把手,帶來很大的便捷性。

  1. 返回一個經過回掉函數處理的新數組;
  2. 不對原數組產生影響。
var a1 = [1, 4, 9];
var a2 = a1.map(Math.sqrt);
a1 //[1, 4, 9]
a2 //[1, 2, 3]

reduce

reduce() 方法接收一個函數作為累加器(accumulator),數組中的每個值(從左到右)開始合并,最終為一個值。 

reduce 是一個合并的過程,從左到右,直到把所有元素合并到一起,并返回最終的結果。它接受兩個參數,第一個參數是一個回掉函數,第二個參數是一個初始值,表示處理第一個元素時的前一個值。這個回掉函數接受四個參數,依次是 accumulator(上次處理的結果),currentValue(當前元素的值),index(當前元素索引),array(調用 reduce 的數組)。

  1. 返回最終合并的結果,即回掉函數的輸出,可以為字符串,對象,數組等任意結果;
  2. 不對原數組產生影響。
var getAdd = (pre, cur) => pre + cur;
var a1 = [1, 2, 3];
var a2 = a1.reduce(getAdd, 0);
a1 //[1, 2, 3]
a2 //6

reduceRight

reduceRight() 方法接受一個函數作為累加器(accumulator),讓每個值(從右到左,亦即從尾到頭)縮減為一個值。(與 reduce() 的執行方向相反)

var toStr = (pre, cur) => '' + pre + cur;
var a1 = [1, 2, 3];
var a2 = a1.reduce(toStr, '');
a2 //"123"
a2 = a1.reduceRight(toStr, '');
a2 //"321"

push

push() 方法添加一個或多個元素到數組的末尾,并返回數組新的長度(length 屬性值)。

如果把數組當作棧,push pop 操作是棧進和出,而往往很多人會忽略函數執行后的返回值。

  1. 返回 push 操作執行之后數組的長度;
  2. 肯定改變。
var a1 = [1, 2, 3];
var a2 = a1.push(4);
a1 //[1, 2, 3, 4]
a2 //4

pop

pop() 方法刪除一個數組中的最后的一個元素,并且返回這個元素。 

  1. 返回刪除的這個元素;
  2. 肯定改變。
var a1 = [1, 2, 3];
var a2 = a1.pop();
a1 //[1, 2]
a2 //3

unshift

unshift() 方法在數組的開頭添加一個或者多個元素,并返回數組新的 length 值。

  1. 返回 length 值;
  2. 肯定改變。
var a1 = [1, 2, 3];
var a2 = a1.unshift(4);
a1 //[4, 1, 2, 3]
a2 //4

shift

shift() 方法刪除數組的 第一個 元素,并返回這個元素。該方法會改變數組的長度。 

shift 方法和 push 方法可以組成一個隊列的操作啦。

  1. 返回刪除的這個元素;
  2. 肯定改變。

reverse

reverse() 方法顛倒數組中元素的位置。第一個元素會成為最后一個,最后一個會成為第一個。 

  1. 函數返回值是修改了的原數組;
  2. 原數組會修改。
var a1 = [1, 2, 3];
var a2 = a1.reverse();
a1 //[3, 2, 1]
a1 === a2; //true

slice

slice() 方法會淺復制(shallow copy)數組的一部分到一個新的數組,并返回這個新數組。 

slice 的參數包括拷貝的初識位置,結束位置(左閉右開),與 splice 有區別。由于不會改變原數組,這個數組可以用于前拷貝,比如經常看別人使用: arr.slice(0) ,表示拷貝數組。

  1. 返回淺拷貝后的新數組;
  2. 不會改變原數組。
var a1 = [1, 2, 3, 4, 5];
var a2 = a1.slice(1, 3);
a1 //[1, 2, 3, 4, 5]
a2 //[2, 3]

splice

splice() 方法用新元素替換舊元素,以此修改數組的內容。 

如其名,分割,會修改原數組的內容,返回一個新數組,而且它的參數也比較多,第一個參數表示初始位置,第二個參數表示分割長度,第三個參數及以后表示分割后在分割處添加新元素。

  1. 返回分割的元素組成的數組;
  2. 會對數組進行修改,原數組會減去分割數組。
var a1 = [1, 2, 3, 4];
var a2 = a1.splice(1, 2);
a1 //[1, 4]
a2 //[2, 3]
a1 = [1, 2, 3, 4];
a2 = a1.splice(1, 2, 5, 6);
a1 //[1, 5, 6, 4]

some

some() 方法測試數組中的某些元素是否通過了指定函數的測試。 

sort

sort() 方法對數組的元素做原地的排序,并返回這個數組。 sort 排序可能是不穩定的。默認按照字符串的Unicode碼位點(code point)排序。 

sort 函數用于排序,比較常用,若沒有制定排序函數,則按照 unicode 位點進行排序,而且數字會被轉成字符串,所以 ‘123’ 要排在 ‘11’ 的后面。

我們會用 sort 做一些有意思的排序,比如漢字按照拼音排序。

  1. 返回排序后的原數組;
  2. 會對數組進行修改。
var big = function(a, b){
  return a - b;
}
var a1 = [2, 4, 77, 1];
var a2 = a1.sort(big);
a1 //[1, 2, 4, 77]
a1 === a2; //true

localeCompare 可以對漢字進行排序,當同時出現漢字和字母的時候會有 bug:

var sort_py = function(a, b){
  return a.localeCompare(b);
}
var a1 = ["北京", "上海", "南京", "合肥"];
a1.sort(sort_py);
//["北京", "合肥", "南京", "上海"]

toString

toString() 返回一個字符串,表示指定的數組及其元素。 

顯然,這個方法和 join 方法比較一下。

  1. 返回拼接的字符串;
  2. 不會改變原數組。
var a1 = [1, 2, 3];
var a2 = a1.toString();
a2 //"1,2,3"

ES6 中新添的數組方法

上面的這些方法都是 ES5 的,來看看 ES6 添加了哪些新方法。

copyWithin

copyWithin() 方法會淺拷貝數組的部分元素到同一數組的不同位置,且不改變數組的大小,返回該數組。 

接受三個參數,分別是要拷貝到的位置 target,拷貝開始位置 start 和結束位置 end。

  1. 返回修改了的原數組;
  2. 會對數組進行修改,且是淺拷貝;
  3. 參數可負,負值時倒推,且 end 為空表示數組長度。
var a1 = [1, 2, 3, 4, 5];
var a2 = a1.copyWithin(0, 2, 4);
a1 //[3, 4, 3, 4, 5]
a2 //[3, 4, 3, 4, 5]
a1 === a2; //true

find

如果數組中某個元素滿足測試條件,find() 方法就會返回滿足條件的第一個元素,如果沒有滿足條件的元素,則返回 undefined。 MDN array.find

  1. 返回找到的那個元素,若未找到,返回 underfined
  2. 不對原數組產生影響。
function isBigEnough(element, index, array) {
  return (element >= 10);
}
var a1 = [8, 18, 14];
var num = a1.find(isBigEnough); //18

findIndex

findIndex()方法用來查找數組中某指定元素的索引, 如果找不到指定的元素, 則返回 -1。 

這個方法可以參考 find 方法,只是返回值是元素的索引而非元素本身。

fill

使用 fill() 方法,可以將一個數組中指定區間的所有元素的值, 都替換成或者說填充成為某個固定的值。 

fill 方法接受三個參數,第一個參數 value 表示要填充到值,后面兩個 start 和 end 表示開始和結束位置,可選,且左閉右開。

  1. 函數返回值是修改了的原數組;
  2. 可對數組產生影響。
var a1 = [1, 2, 3, 4, 5];
var a2 = a1.fill(6, 1, 4);
a1 //[1, 6, 6, 6, 5]
a2 //[1, 6, 6, 6, 5]
a1 === a2; //true

keys

數組的 keys() 方法返回一個數組索引的迭代器。 

這個方法會返回一個數組索引的迭代器,迭代器在 ES6 中有特殊的用途。

  1. 函數返回一個迭代器對象;
  2. 不會改變原數組。
var arr = ["a", "b", "c"];
var iterator = arr.keys();

console.log(iterator.next()); // { value: 0, done: false }
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: undefined, done: true }

entries

entries() 方法返回一個 Array Iterator 對象,該對象包含數組中每一個索引的鍵值對。 

var arr = ["a", "b", "c"];
var eArr = arr.entries();

console.log(eArr.next().value); // [0, "a"]
console.log(eArr.next().value); // [1, "b"]
console.log(eArr.next().value); // [2, "c"]

includes

includes() 方法用來判斷當前數組是否包含某指定的值,如果是,則返回 true,否則返回 false。 

該函數接受兩個參數,第二個參數表示開始查找位置,起始位置為 0。這個方法與 indexOf 方法最大的區別不僅在于返回值一個是索引,一個是布爾值,indexOf 方法使用的是 === 來判斷,無法判斷 NaN 情況,而 includes 可以判斷。

  1. 返回 true 或 false;
  2. 不會改變原數組。
var a1 = [1, NaN];
a1.indexOf(NaN);//-1
a1.includes(NaN);//true

 

來自:http://yuren.space/blog/2017/01/15/array-function/

 

 本文由用戶 gidi521 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!