【js進階系列】一文學會31個數組方法

前面的話

番外

JS數組上的方法太多了,有的修改原數組,有的返回一個新數組,記住了又混淆了,因此我決定關上書本一個都不記! 哼!用的時候再說吧。html

而後每出現一個數組方法的時候看着都知道,就是用的時候仍是模棱兩可,又去查文檔,這樣是不能算做精通JavaScript的哦,因而玲瓏好好的把每一個方法認真複習、認真總結、認真的寫了一篇博客(認真三連嘻嘻嘻)。es6

文章介紹

Array對象是js中的重點,面試題中常常出現,平時的項目中也少不了對數組的操做。一直一直都想對數組作一個整理。面試

這篇文章將會詳細介紹數組的9+9+13個方法(包括es6中對數組擴展的一些新方法)。每一個方法的傳參要求,返回值,是否對原數組進行修改等等都在文中詳細說明,你們能夠收藏方便往後查閱。算法


在開始以前咱們先對數組對象作一個簡單的回顧。先來看看Array對象上的一些屬性和方法。以及建立數組實例的方式。

如何建立一個數組實例

(一)使用 Array 構造函數: 在es5中建立一個數組有兩種方法。數組

var arr1 = new Array(); //建立一個空數組
var arr2 = new Array(20); // 建立一個包含20項的數組
var arr3 = new Array("lily","lucy","Tom"); // 建立一個包含3個字符串的數組
複製代碼

(二)使用數組字面量表示法:瀏覽器

var arr4 = []; //建立一個空數組
var arr5 = [20]; // 建立一個包含1項的數組
var arr6 = ["lily","lucy","Tom"]; // 建立一個包含3個字符串的數組
複製代碼

Array對象的方法

Array對象自身有三個方法。bash

Array.isArray()

判斷傳入該方法的值是否是一個Array,返回值是布爾類型。函數

Array.isArray([1, 2, 3]);  
// true
Array.isArray({foo: 123}); 
// false
Array.isArray("foobar");   
// false
Array.isArray(undefined);  
// false
複製代碼

(ES6擴展)Array.of()

定義:返回由全部參數值組成的數組,若是沒有參數,就返回一個空數組。post

目的:Array.of() 出現的目的是爲了解決上述構造器因參數個數不一樣,致使的行爲有差別的問題。測試

栗子:這裏舉例來講明of方法到底解決了什麼問題。

Array();//[]即一個空數組
Array(3);//[ , , ]一個length==3的空數組
Array(1, 2, 3);//[1, 2, 3]

//of方法
let a = Array.of(3, 11, 8); // [3,11,8]
let b = Array.of(3); // [3]  b.length ==1

複製代碼

咱們new Array生成一個新數組的時候,會由於傳遞的參數不一樣而作出不一樣的解釋,當參數大於等於2的時候會將參數做爲數組的值,0或1個參數是指數組的length的值。length的值就是傳入的一個參數的值,上面例子中傳入一個參數3,那麼這個數組的length==3.可是of方法就不會出現這種不統一的問題。

(ES6擴展)Array.from()

定義:用於將兩類對象(類數組對象/可遍歷對象)轉爲真正的數組(不改變原對象,返回新的數組)。

參數: 第一個參數(必需):要轉化爲真正數組的對象。 第二個參數(可選): 相似數組的map方法,對每一個元素進行處理,將處理後的值放入返回的數組。 第三個參數(可選): 用來綁定this。

舉例: 舉一個類數組對象的例子。

//一個類數組
    let arrLike = {
            '0': '玲瓏',
            '1': '仍是',
            '2': '一個',
            '3': '小白',
            length: 4
        }
        //es5中使用call改變this指向
        var arr1 = [].slice.call(arrLike);
        console.log(arr1);          //["玲瓏", "仍是", "一個", "小白"]
        
        //es6中的擴展from方法
        let arr2 = Array.from(arrLike);
        console.log(arr2);          //["玲瓏", "仍是", "一個", "小白"]
複製代碼

有了from方法就不用call方法將類數組改爲數組了。

Array對象的屬性

  • Array對象上有三個屬性,訪問器屬性返回Array的構造函數。
  • Array 構造函數的 length 屬性,其值爲1(注意該屬性爲靜態屬性,不是數組實例的 length 屬性)。
  • prototype屬性,Array.prototype 經過數組的原型對象能夠爲全部數組對象添加屬性。全部數組實例都會從 Array.prototype 繼承屬性和方法。修改 Array 的原型會影響到全部的數組實例。 (就是說當建立一個數組實例的時候默認繼承到了Array.prototype上的屬性和方法。若是對原型上的方法進行修改,那麼實例的數組會繼承修改了的數組方法。)

仍是不明白就看一個代碼吧。咱們自動在原型上面添加一個將字符數組轉大寫的方法myUcase。看看最後的結果截圖。

let a = new Array('linglong', 'is', 'a', 'cool' , 'girl');
       
Array.prototype.myUcase = function(){
   for (i=0;i<this.length;i++){
   	this[i]=this[i].toUpperCase();
   }
}
a.myUcase();
console.log(a);
複製代碼

看控制檯的結果顯示的是一個length==5的數組,翻譯一下玲瓏是一個酷酷的女孩

這下明白了吧,數組對象原型上增長了一個方法,那麼實例出來的數組會繼承這個方法。

前面的內容都是開胃菜,接下來是主要的知識點---Array原型對象上的方法。 若是你看不先去了,請記住數組對象Array上只有三個方法,其它的是像pop,fill,reserve等數組方法都是Array對象的prototype對象上的方法。


咱們建立的數組可以擁有這些方法是由於經過數組的的__proto_ _屬性,爲了加深印象再看看下圖黃色高亮部分_proto__指向的是Array原型對象,裏面有許多咱們平時說的數組方法,以下圖所示,其中myUcase是我剛纔人爲添加的。

(這裏只是部分方法不是全部哦)

1、改變原數組的方法

所謂的改變原數組就是不返回新數組,在原有的數組上進行改變。官方文檔中也加修改器方法。這些方法會改變調用它們的對象自身的值。一共有哪些,一塊兒來看看吧。

一、(ES6擴展)Array.prototype.copyWithin()

這個方法淺複製數組的一部分到同一數組中的另外一個位置,並返回它,不會改變原數組的長度。 這個方法能夠接受3個參數。 語法:

```
array.copyWithin(target, start = 0, end = this.length)
```
複製代碼

參數:

三個參數都是數值,若是不是,會自動轉爲數值.

  • target(必需):從該位置開始替換數據。若是爲負值,表示倒數。
  • start(可選):從該位置開始讀取數據,默認爲 0。若是爲負值,表示倒數。
  • end(可選):到該位置中止讀取數據,默認等於數組長度。使用負數可從數組結尾處規定位置。

下面用代碼說話加深理解。整個過程能夠看中選中賦值,而後粘貼的過程。

const array1 = ['a', 'b', 'c', 'd', 'e'];

// copy to index 0 the element at index 3
console.log(array1.copyWithin(0, 3, 4));
// expected output: Array ["d", "b", "c", "d", "e"]

// copy to index 1 all elements from index 3 to the end
console.log(array1.copyWithin(1, 3));
// expected output: Array ["d", "d", "e", "d", "e"]
複製代碼

第一次使用copyWithin方法傳入的第一個參數0表示從第0位開始被複制;第二個參數3表示表示從第三號位置array1[3]=='d'開始選中;第三個參數4表示第四號位置以前選中結束。array1[4]=='e',也就是隻選中d。

將選中的d複製到第0號位置。就獲得告終果["d", "b", "c", "d", "e"]。

後面輸出array1.copyWithin(1, 3)的結果先試着分析一下吧,第三個參數沒有寫就是默認參數當前數組的長度。

二、(ES6擴展)Array.prototype.fill()

將數組中指定區間的全部元素的值,都替換成某個固定的值。 定義: 使用給定值,填充一個數組。

參數:

  • 第一個元素(必須): 要填充數組的值

  • 第二個元素(可選): 填充的開始位置,默認值爲0

  • 第三個元素(可選):填充的結束位置,默認是爲this.length 用代碼說話

['a', 'b', 'c'].fill(7)
    // [7, 7, 7]
    ['a', 'b', 'c'].fill(7, 1, 2)
    // ['a', 7, 'c']
    new Array(3).fill(7);
    //[7, 7, 7]
複製代碼

須要注意的是第三個參數結束位置:是該位置以前結束,好比上面代碼中的第二個例子中只是將1號位置填充爲7.

三、Array.prototype.pop()

定義: pop() 方法刪除一個數組中的最後的一個元素,而且返回這個元素。

參數: 無。

用代碼說話:

let  a =  [1,2,3];
    let item = a.pop();  // 3
    console.log(a); // [1,2]

複製代碼

注意:若是你在一個空數組上調用 pop(),它返回 undefined。

四、Array.prototype.push()

push() 方法將一個或多個元素添加到數組的末尾,並返回該數組的新長度。

定義:push() 方法可向數組的末尾添加一個或多個元素,並返回新的長度。

參數: item1, item2, ..., itemX ,要添加到數組末尾的元素

let  a =  [1,2,3];
    let item = a.push('末尾');  // 4
    console.log(a); // [1,2,3,'末尾']
複製代碼

五、Array.prototype.reverse()

reverse() 方法將數組中元素的位置顛倒,並返回該數組。數組的第一個元素會變成最後一個,數組的最後一個元素變成第一個。該方法會改變原數組。

定義: reverse() 方法用於顛倒數組中元素的順序。

參數: 無。

const array1 = ['one', 'two', 'three'];
console.log('array1:', array1);
// expected output: "array1:" Array ["one", "two", "three"]

const reversed = array1.reverse();
console.log('reversed:', reversed);
// expected output: "reversed:" Array ["three", "two", "one"]

// Careful: reverse is destructive -- it changes the original array.
console.log('array1:', array1);
// expected output: "array1:" Array ["three", "two", "one"]
複製代碼

六、Array.prototype.shift()

shift 方法移除索引爲 0 的元素(即第一個元素),並返回被移除的元素,其餘元素的索引值隨之減 1。若是 length 屬性的值爲 0 (長度爲 0),則返回 undefined。

Array.prototype.pop() 有着和 shift類似的行爲, 可是是做用在數組的最後一個元素上的。

let  a =  [1,2,3];
    let item = a.shift();  // 1
    console.log(a); // [2,3]

複製代碼

七、Array.prototype.sort()

sort() 方法用原地算法對數組的元素進行排序,並返回數組。默認排序順序是在將元素轉換爲字符串,而後比較它們的UTF-16代碼單元值序列時構建的

因爲它取決於具體實現,所以沒法保證排序的時間和空間複雜性。

語法:

arr.sort([compareFunction])
複製代碼

參數:[compareFunction]

這個參數是一個比較函數,一個一個可選參數,用來指定按某種順序進行排列的函數。若是省略,元素按照轉換爲的字符串的各個字符的Unicode位點進行排序。

這個函數有兩個參數,暫且叫作a,b。是在函數中用於比較的參數。

  • 若是 compareFunction(a, b) 小於 0 ,那麼 a 會被排列到 b 以前;
  • 若是 compareFunction(a, b) 等於 0 , a 和 b 的相對位置不變。備註: ECMAScript 標準並不保證這一行爲,並且也不是全部瀏覽器都會遵照(例如 Mozilla 在 2003 年以前的版本);
  • 若是 compareFunction(a, b) 大於 0 , b 會被排列到 a 以前。
function compare(a, b) {
  if (a < b ) {           // 按某種排序標準進行比較, a 小於 b
    return -1;
  }
  if (a > b ) {
    return 1;
  }
  // a must be equal to b
  return 0;
}
複製代碼

栗子:下面看一個簡單的例子。用sort方法將[8,90]這個數組進行排序。分別看看sort方法傳參和不傳參的狀況。

傳參

var numbers = [80,9]; 
// numbers.sort();
 numbers.sort((a, b) => a - b); 
 console.log(numbers);
 //[9, 80]
複製代碼

傳入參數發現9-80小於0,那麼9就在80的前面。

不傳參

var numbers = [80,9]; 
        numbers.sort();
// numbers.sort((a, b) => a - b); 
        console.log(numbers);
        //[80, 9]
複製代碼

不傳參數沒有指明 compareFunction ,那麼元素會按照轉換爲的字符串的諸個字符的Unicode位點進行排序。例如 "Banana" 會被排列到 "cherry" 以前。當數字按由小到大排序時,9 出如今 80 以前,但由於(沒有指明 compareFunction),比較的數字會先被轉換爲字符串,因此在Unicode順序上 "80" 要比 "9" 要靠前。

八、Array.prototype.splice()

該方法刪除或替換現有元素或者添加新元素到數組中去。返回值是由被刪除的元素組成的一個數組。若是隻刪除了一個元素,則返回只包含一個元素的數組。若是沒有刪除元素,則返回空數組。

語法:

array.splice(index,howmany,item1,.....,itemX)
複製代碼

參數:

  • index:必需。整數,規定添加/刪除項目的位置,使用負數可從數組結尾處規定位置。
  • howmany:可選。要刪除的項目數量。若是設置爲 0,則不會刪除項目。
  • item1, ..., itemX: 可選。向數組添加的新項目。

經過四個代碼來看看傳入不一樣的的參數返回值以及數組的變化狀況

傳入三個參數都爲正

var myFish = ["angel", "clown", "mandarin", "sturgeon"];
var removed = myFish.splice(2, 0, "drum");

// 運算後的 myFish: ["angel", "clown", "drum", "mandarin", "sturgeon"]
// 被刪除的元素: [], 沒有元素被刪除
複製代碼

splice方法第一個參數2說明從myFish[2]這個位置進行相關操做,第二個參數是0說明不刪除項目;第三個參數說明添加‘drum’第2號位置上。

傳入兩個參數爲正

var myFish = ['angel', 'clown', 'drum', 'mandarin', 'sturgeon'];
var removed = myFish.splice(3, 1);

// 運算後的 myFish: ["angel", "clown", "drum", "sturgeon"]
// 被刪除的元素: ["mandarin"]
複製代碼

從第三號位置上刪除1個元素,將三號元素刪除。

傳入2個參數第一個爲負

從倒數第二個位置開始進行刪除或者是添加操做(最後一個元素是-1位置),只有兩個參數那麼就是刪除,而且刪除元素的個數是2,因此從‘mandarin’開始日後刪除2個元素就ok了。

傳入一個參數

var myFish = ['angel', 'clown', 'mandarin', 'sturgeon'];
var removed = myFish.splice(2);

// 運算後的 myFish: ["angel", "clown"]
// 被刪除的元素: ["mandarin", "sturgeon"]
複製代碼

從第二個位置開始刪除後面的全部元素。

九、Array.prototype.unshift()

unshift() 方法將一個或多個元素添加到數組的開頭,並返回該數組的新長度(該方法修改原有數組)。

語法:

arr.unshift(element1, ..., elementN)
複製代碼

參數列表:有多個參數表示添加到開頭的元素。

let arr = [4,5,6];
arr.unshift(1,2,3);
console.log(arr); // [1, 2, 3, 4, 5, 6]

arr = [4,5,6]; // 重置數組
arr.unshift(1);
arr.unshift(2);
arr.unshift(3);
console.log(arr); // [3, 2, 1, 4, 5, 6]
複製代碼

上述方法總結

上面九個都是修改器方法,有兩個是es6新增的方法,copyWithin和fill方法。其餘是es5就有的。

  • Array.prototype.copyWithin() 在數組內部,將一段元素序列拷貝到另外一段元素序列上,覆蓋原有的值。
  • Array.prototype.fill() 將數組中指定區間的全部元素的值,都替換成某個固定的值。
  • Array.prototype.pop() 刪除數組的最後一個元素,並返回這個元素。
  • Array.prototype.push() 在數組的末尾增長一個或多個元素,並返回數組的新長度。
  • Array.prototype.reverse() 顛倒數組中元素的排列順序,即原先的第一個變爲最後一個,原先的最後一個變爲第一個。
  • Array.prototype.shift() 刪除數組的第一個元素,並返回這個元素。
  • Array.prototype.sort() 對數組元素進行排序,並返回當前數組。
  • Array.prototype.splice() 在任意的位置給數組添加或刪除任意個元素。
  • Array.prototype.unshift() 在數組的開頭增長一個或多個元素,並返回數組的新長度。 訪問方法

2、不改變原數組的方法

不改變原數組的方法也稱做訪問方法。就是返回一個新的數組或者其餘,不會對原來的數組產生影響。

一、Array.prototype.concat()

這個方法用於合併兩個或者多個數組,會返回合併後的新數組。該方法的參數能夠是具體的值好比123,也能夠是數組。

let a = [1, 2, 3];
    let b = [4, 5, 6];
    //鏈接兩個數組
    let newVal=a.concat(b); // [1,2,3,4,5,6]
    // 鏈接三個數組
    let c = [7, 8, 9]
    let newVal2 = a.concat(b, c); // [1,2,3,4,5,6,7,8,9]
    // 添加元素
    let newVal3 = a.concat('添加元素',b, c,'再加一個'); 
    // [1,2,3,"添加元素",4,5,6,7,8,9,"再加一個"]
   // 合併嵌套數組  會淺拷貝嵌套數組
   let d = [1,2 ];
   let f = [3,[4]];
   let newVal4 = d.concat(f); // [1,2,3,[4]]

複製代碼

將值鏈接到數組

var alpha = ['a', 'b', 'c'];

var alphaNumeric = alpha.concat(1, [2, 3]);

console.log(alphaNumeric); 
// results in ['a', 'b', 'c', 1, 2, 3]
複製代碼

將值鏈接到數組要與嵌套數組區別開來哦,值鏈接到數組是由於該方法的參數形式不僅有一種,但最後都是將參數鏈接到數組中去。

(延伸)es6中的擴展運算符

這裏是數組的鏈接,在es6中新增的擴展運算符...也可以將多個數組拼接。代碼也更加簡潔

let a = [2, 3, 4, 5]
    let b = [ 4,...a, 4, 4]
    console.log(a,b); //  [2, 3, 4, 5] [4,2,3,4,5,4,4]
複製代碼

二、Array.prototype.indexOf()

定義: 返回在數組中能夠找到一個給定元素的第一個索引,若是不存在,則返回-1。

語法:

array.indexOf(searchElement,fromIndex)
複製代碼

參數:

searchElement(必須):被查找的元素

fromIndex(可選):開始查找的位置(不能大於等於數組的長度,返回-1),接受負值,默認值爲0.

var array = [2, 5, 9];
array.indexOf(2);     // 0
array.indexOf(7);     // -1
array.indexOf(9, 2);  // 2
array.indexOf(2, -1); // -1
array.indexOf(2, -3); // 0

var array = [2, 5, 9];
console.log(array.indexOf(2, -2));
//-1
複製代碼

這裏要說明的是:

第二個可選參數是負數的時候,若是是負數表示從末尾開始查找,查找的順序也是從前日後的,好比上面的例子array.indexOf(2, -1)中的-1表示從數組的倒數第一位9這個值開始查找,從9這個位置a[-1]日後查找是否存在2,發現沒有返回-1;array.indexOf(2, -3); // 0中的-3表示從倒數第三個位置(a[0])開始從前日後查詢2,發現第0號位置恰好是2,結果返回0.

若是第二個參數是負數而且絕對值大於數組的長度那麼整個數組都會被查詢,至關於默認值0。看看下面的截圖你就知道啦

第二個參數是-4或者-5的時候,其絕對值大於數組的長度3,至關於從頭開始查找。

注意:indexOf方法有兩個缺點

  • 不夠語義化,理解起來比較麻煩
  • 內部使用嚴格===進行判斷會致使NaN出錯,可是includes方法就不會。
[NaN].indexOf(NaN)//-1
複製代碼

三、(ES6擴展)Array.prototype.includes()

includes() 方法用來判斷一個數組是否包含一個指定的值,根據狀況,若是包含則返回 true,不然返回false。

參數:

searchElement(必須): 被查找的元素

fromIndex(可選): 默認值爲0,參數表示搜索的起始位置,接受負值。正值超過數組長度,數組不會被搜索,返回false。負值絕對值超過長數組度,重置從0開始搜索。

說明:

把includes方法放到indexOf方法的後面是由於首字母都是i嘛,固然不是。而是由於includes方法解決了前面indexOf的兩個缺陷。返回值是布爾值而不是數組元素的位置索引號更加清晰,而後NaN的問題也不存在了。

[NaN].includes[NaN]//true
複製代碼

四、Array.prototype.lastIndexOf()

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

語法:

arr.lastIndexOf(searchElement,fromIndex)
複製代碼

參數: searchElement(必須): 被查找的元素

fromIndex(可選): 逆向查找開始位置,默認值數組的長度-1,即查找整個數組。 關於fromIndex有三個規則:

  • 正值。若是該值大於或等於數組的長度,則整個數組會被查找。

  • 負值。將其視爲從數組末尾向前的偏移。(好比-2,從數組最後第二個元素開始往前查找)

  • 負值。其絕對值大於數組長度,則方法返回 -1,即數組不會被查找。

let a=['OB',4,'Koro1',1,2,'Koro1',3,4,5,'Koro1']; // 數組長度爲10
 // let b=a.lastIndexOf('Koro1',4); // 從下標4開始往前找 返回下標2
 // let b=a.lastIndexOf('Koro1',100); //  大於或數組的長度 查找整個數組 返回9
 // let b=a.lastIndexOf('Koro1',-11); // -1 數組不會被查找
 let b=a.lastIndexOf('Koro1',-9); // 從第二個元素4往前查找,沒有找到 返回-1
複製代碼

五、Array.prototype.join()

join() 方法將一個數組(或一個類數組對象)的全部元素鏈接成一個字符串並返回這個字符串。若是數組只有一個項目,那麼將返回該項目而不使用分隔符。在強調一下返回的是字符串字符串字符串;若是 arr.length 爲0,則返回空字符串。

語法:

array.join(str)
複製代碼

參數: str(可選): 指定要使用的分隔符,默認使用逗號做爲分隔符。若是參數是空字符串(""),則全部元素之間都沒有任何字符。

var a = ['Wind', 'Rain', 'Fire'];
var myVar1 = a.join();      // myVar1的值變爲"Wind,Rain,Fire"
var myVar2 = a.join(', ');  // myVar2的值變爲"Wind, Rain, Fire"
var myVar3 = a.join(' + '); // myVar3的值變爲"Wind + Rain + Fire"
var myVar4 = a.join('');    // myVar4的值變爲"WindRainFire"
複製代碼

六、Array.prototype.slice()

slice() 方法返回一個新的數組對象,這一對象是一個由 begin 和 end 決定的原數組的淺拷貝(包括 begin,不包括end)。原始數組不會被改變。

語法:

array.slice(begin, end);
複製代碼

參數:

begin(包括改位置,可選參數):

  • 拷貝的起始位置索引,若是是負數表示從倒數第幾位開始拷貝,slice(-2) 表示提取原數組中的倒數第二個元素到最後一個元素(包含最後一個元素)。
  • 默認值是0。
  • 若是值大於數組的長度會返回一個空數組。

end(不包括該位置,可選參數)

  • 拷貝的結束位置,默認值是數組的長度
  • 負數表示從倒數第幾位開始,slice(-2,-1) 表示抽取了原數組中的倒數第二個元素到最後一個元素(不包含最後一個元素,也就是隻有倒數第二個元素)。
var fruits = ['Banana', 'Orange', 'Lemon', 'Apple', 'Mango'];
var citrus = fruits.slice(1, 3);

// fruits contains ['Banana', 'Orange', 'Lemon', 'Apple', 'Mango']
// citrus contains ['Orange','Lemon']
複製代碼

淺拷貝舉例

slice是對數組的淺拷貝,拷貝的時候有如下規則

  • 若是拷貝的元素是普通數據類型,向Number、String那麼修改新數組對原數組沒有影響。
let a= ['hello','world'];
    let b=a.slice(0,1); // ['hello']
    a[0]='改變原數組';
    console.log(a,b); // ['改變原數組','world'] ['hello']
    b[0]='改變拷貝的數組';
    console.log(a,b); // ['改變原數組','world'] ['改變拷貝的數組']

複製代碼
  • 若是拷貝的元素自己就是引用類型,好比對象和數組那麼改變新數組或者原數組都會產生影響。這是由於slice拷貝的是對象的引用,兩個數組的元素都是引用的同一個對象,若是被引用的對象發生改變,則新的和原來的數組中的這個元素也會發生改變。
let arr = [{name:'LINGLONG', explain:'我是原數組'}];
let arr2 = arr.slice();
// console.log(arr2);
arr[0].explain = '修改的原數組';
console.log(arr2); //[{name: "LINGLONG", explain: "修改的原數組"}]
複製代碼

七、Array.prototype.toSource()

遮蔽了原型鏈上的 Object.prototype.toSource() 方法。返回一個字符串,表明該數組的源代碼.

var alpha = new Array("a", "b", "c");
alpha.toSource();   //返回["a", "b", "c"]
複製代碼

該方法是非標準的,儘可能不要在開發環境使用。而且只有火狐的安卓瀏覽器兼容,在谷歌瀏覽器中是找不到這個方法的。

谷歌瀏覽器下沒有這個方法

八、Array.prototype.toString()

  • 返回一個由全部數組元素組合而成的字符串。遮蔽了原型鏈上的Object.prototype.toString() 方法.

咱們先看看Object上的toString方法,你們都知道他可以判斷一個值的類型。

var toString = Object.prototype.toString;

toString.call(new Date); // [object Date]
toString.call(new String); // [object String]
toString.call(Math); // [object Math]

//Since JavaScript 1.8.5
toString.call(undefined); // [object Undefined]
toString.call(null); // [object Null]
複製代碼

而數組的toString返回的是一個字符串,可是該方法的效果和join方法不傳參數同樣,都是用於數組轉字符串的,可是與join方法相比沒有優點,也不能自定義字符串的分隔符,所以不推薦使用。

const array1 = [1, 2, 'a', '1a'];
console.log(array1.toString());
// expected output: "1,2,a,1a"
複製代碼
  • 當一個數組被做爲文本值或者進行字符串鏈接操做時,將會自動調用其 toString 方法。
let b= [ 'toString','演示'].toString(); // toString,演示
   let a= ['調用toString','鏈接在我後面']+'啦啦啦'; // 調用toString,鏈接在我後面啦啦啦
複製代碼

九、Array.prototype.toLocaleString()

這是不改變原數組的最後一個方法啦。該方法返回一個字符串表示數組中的元素。數組中的元素將使用各自的 toLocaleString 方法轉成字符串,這些字符串將使用一個特定語言環境的字符串(例如一個逗號 ",")隔開。

語法:

arr.toLocaleString([locales[,options]]);
複製代碼

參數:

  • locals,可選參數: 帶有BCP 47語言標記的字符串或字符串數組。關於這裏我認爲是和html中的lang屬性規定元素的代碼語言相似吧
  • options,可選參數: options 參數必須是一個對象,其屬性值在不一樣的構造函數和方法中會有所變化。 對於數字Number.prototype.toLocaleString(),對於日期Date.prototype.toLocaleString().

關於參數的問題建議查閱官方文檔Array.prototype.toLocaleString()

const array1 = [1, 'a', new Date('21 Dec 1997 14:12:00 UTC')];
const localeString = array1.toLocaleString('en', {timeZone: "UTC"});

console.log(localeString);
// expected output: "1,a,12/21/1997, 2:12:00 PM",
// This assumes "en" locale and UTC timezone - your results may vary
複製代碼

上例子中arr1數字的1是數字,使用Number.prototype.toLocaleString();日期是Date.prototype.toLocaleString().

3、數組的遍歷方法(不改變原數組)

一、Array.prototype.forEach()

語法:

array.forEach(function(currentValue, index, arr), thisValue)
複製代碼

參數:

  • function(currentValue, index, arr):數組中每一個元素都可以執行的函數,這個函數有三個參數currentValue, index, arr。
// 回調函數的參數
    1. currentValue(必須),數組當前元素的值
    2. index(可選), 當前元素的索引值
    3. arr(可選),數組對象自己
複製代碼
  • thisValue:是一個可選參數,當執行回調函數的時候表示this的值,也就是回調函數內的this指向thisValue。
const array1 = ['a', 'b', 'c'];

array1.forEach(element => console.log(element));
複製代碼

稀疏數組的forEach

const arraySparse = [1,3,,7];
let numCallbackRuns = 0;

arraySparse.forEach(function(element){
  console.log(element);
  numCallbackRuns++;
});

console.log("numCallbackRuns: ", numCallbackRuns);

// 1
// 3
// 7
// numCallbackRuns: 3
複製代碼

arraySpare就是一個稀疏數組,a[2]是空,那麼該方法不會對這個空數組元素有效,於是回調函數只執行3次。

若是數組在迭代時被修改了,則其餘元素會被跳過。

var words = ['one', 'two', 'three', 'four'];
words.forEach(function(word) {
  console.log(word);
  if (word === 'two') {
    words.shift();
  }
});
// one
// two
// four
複製代碼

當數組元素是two的時候就會移除掉0號位置的數組元素,shift方法會改變原數組,此時的words==[ 'two', 'three', 'four']。前面的兩個位置的元素遍歷過了,那麼three就被跳過,遍歷four這個元素。

上面這個例子我讓word==‘one’的時候移除第一個元素。原數組變成['two', 'three', 'four'],第一個元素被遍歷了,此時two在第一個元素的位置(0號位置)因此two被跳過。

二、Array.prototype.every()

every() 方法測試一個數組內的全部元素是否都能經過某個指定函數的測試。它返回一個布爾值。

若收到一個空數組,那麼任何操做都返回true

語法:

array.every(function(currentValue, index, arr), thisValue)
複製代碼

參數:同forEach

function isBigEnough(element, index, array) { 
      return element >= 10; // 判斷數組中的全部元素是否都大於10
    }
    let result = [12, 5, 8, 130, 44].every(isBigEnough);   // false
    let result = [12, 54, 18, 130, 44].every(isBigEnough); // true
    // 接受箭頭函數寫法 
    [12, 5, 8, 130, 44].every(x => x >= 10); // false
    [12, 54, 18, 130, 44].every(x => x >= 10); // true

複製代碼

說明:若是回調函數的每一次返回都爲 truthy 值,返回 true ,不然返回 false。

三、Array.prototype.some()

這個方法和前面的every方法對立,every方法規定每一個元素都可以經過指定函數的測試,some方法只用一個元素可以經過指定函數的測試。

若是用一個空數組進行測試,在任何狀況下它返回的都是false

語法參數都比較相似

arr.some(callback(element[, index[, array]])[, thisArg])
複製代碼

用代碼說話:

function isBiggerThan10(element, index, array) {
  return element > 10;
}

[2, 5, 8, 1, 4].some(isBiggerThan10);  // false
[12, 5, 8, 1, 4].some(isBiggerThan10); // true
複製代碼

四、Array.prototype.filter()

filter自己就有過濾的意思,該方法返回一個新數組,這個數組的元素就是聽過測試的元素。

語法:

var newArray = arr.filter(callback(element[, index[, array]])[, thisArg])
複製代碼

參數同some等方法同樣,一個必填的函數參數和一個可選的thisValue。

用代碼說話,過濾出大於10的元素。

function isBigEnough(element) {
  return element >= 10;
}
var filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
// filtered is [12, 130, 44] 
複製代碼

五、Array.prototype.map()

map() 方法建立一個新數組,其結果是該數組中的每一個元素都調用一個提供的函數後返回的結果。 語法參數同上。

var numbers = [1, 4, 9];
var roots = numbers.map(Math.sqrt);
// roots的值爲[1, 2, 3], numbers的值仍爲[1, 4, 9]
複製代碼

六、Array.prototype.reduce()(方法參數不通常)

這個方法返回的是一個函數處理的累計結果。數組中的每一個元素執行一個由您提供的reducer函數(升序執行),將其結果彙總爲單個返回值。

語法:

array.reduce(callback(total, currentValue, currentIndex, arr), initialValue)
複製代碼

參數:

  • callback()
    • total(必須),初始值或者上一次回調函數返回的值。若是initialValue存在初始值就是initialValue,若是不存在就是數組的第一個元素。
    • currentValue當前值,若是initialValue不存在就是下標爲1的元素(第二個元素);若是initialValue存在就是下標爲0的元素。
    • currentIndex可選參數,數組中正在處理的當前元素的索引。 若是提供了initialValue,則起始索引號爲0,不然從索引1起始。
    • arr:可選參數,調用reduce方法的數組。
  • initialValue:可選參數,做爲第一次調用 callback函數時的第一個參數的值。 若是沒有提供初始值,則將使用數組中的第一個元素。 在沒有初始值的空數組上調用 reduce 將報錯。

用代碼說話:傳入兩個參數和一個參數的結果不一樣。

const array1 = [1, 2, 3, 4];
const reducer = (accumulator, currentValue) => accumulator + currentValue;

// 1 + 2 + 3 + 4
console.log(array1.reduce(reducer));
// expected output: 10

// 5 + 1 + 2 + 3 + 4
console.log(array1.reduce(reducer, 5));
// expected output: 15
複製代碼

注意:若是沒有提供initialValue,reduce 會從索引1的地方開始執行 callback 方法,跳過第一個索引。若是提供initialValue,從索引0開始。

七、Array.prototype.reduceRight()

這個方法同reduce方法惟一的區別是從數組的右邊開始返回函數處理的累計結果,語法參數都同樣,直接看代碼。

const array1 = [[0, 1], [2, 3], [4, 5]].reduceRight(
  (accumulator, currentValue) => accumulator.concat(currentValue)
);

console.log(array1);
// expected output: Array [4, 5, 2, 3, 0, 1]
複製代碼

八、9(ES6擴展)find()和findIndex()

find()定義:用於找出第一個符合條件的數組成員,並返回該成員,若是沒有符合條件的成員,則返回undefined。

findIndex()定義:返回第一個符合條件的數組成員的位置,若是全部成員都不符合條件,則返回-1。

區別:這兩個方法返回的都要知足測試的函數。可是一個是返回符合條件元素的值,一個是返回符合條件元素的下標。

語法:

let new_array = arr.find(function(currentValue, index, arr), thisArg)
    let new_array = arr.findIndex(function(currentValue, index, arr), thisArg)
複製代碼

二者參數的意義和前面的map那四個遍歷方法同樣。

用代碼說話

//find()
const array1 = [5, 12, 8, 130, 44];

const found = array1.find(element => element > 10);

console.log(found);
// expected output: 12

//findIndex
const array1 = [5, 12, 8, 130, 44];

const isLargeNumber = (element) => element > 13;

console.log(array1.findIndex(isLargeNumber));
// expected output: 3
複製代碼

與indexOf的比較

  • 這兩個方法均可以識別NaN,彌補了indexOf的不足.原理是藉助了Object.is方法。
// find
        let a = [1, 4, -5, 10].find((n) => n < 0); // 返回元素-5
        let b = [1, 4, -5, 10,NaN].find((n) => Object.is(NaN, n));  // 返回元素NaN
        // findIndex
        let a = [1, 4, -5, 10].findIndex((n) => n < 0); // 返回索引2
        let b = [1, 4, -5, 10,NaN].findIndex((n) => Object.is(NaN, n));  // 返回索引4
複製代碼
  • 若是你須要找到一個元素的位置或者一個元素是否存在於數組中,使用Array.prototype.indexOf() 或 Array.prototype.includes()。

十、十一、12(ES6擴展)數組實例的entries()、keys()、values()

它們都返回一個遍歷器對象,能夠用for...of循環進行遍歷,惟一的區別是

  • keys()是對鍵名的遍歷
const array1 = ['a', 'b', 'c'];
const iterator = array1.keys();

for (const key of iterator) {
  console.log(key);
}

// expected output: 0
// expected output: 1
// expected output: 2

複製代碼
  • values()是對鍵值的遍歷
const array1 = ['a', 'b', 'c'];
const iterator = array1.values();

for (const value of iterator) {
  console.log(value);
}

// expected output: "a"
// expected output: "b"
// expected output: "c"

複製代碼
  • entries()是對鍵值對的遍歷。
const array1 = ['a', 'b', 'c'];

const iterator1 = array1.entries();

console.log(iterator1.next().value);
// expected output: Array [0, "a"]

console.log(iterator1.next().value);
// expected output: Array [1, "b"]
複製代碼

1三、Array.prototype[@@iterator ]

這是這篇文章的最後一個方法,在阮一峯的es6標準入門一書中並無說起。可是官方文檔整理了這是es6新增的方法,這裏仍是說一下吧。

這個方法默認狀況下,與 values() 返回值相同, arr[Symbol.iterator] 則會返回 values() 函數。

語法:arr[Symbol.iterator]()
複製代碼

用代碼說話:

function logIterable(it) {
  var iterator = it[Symbol.iterator]();
  // 瀏覽器必須支持 for...of 循環
  for (let letter of iterator) {
      console.log(letter);
  }
}

// Array
logIterable(['a', 'b', 'c']);
// a
// b
// c

// string
logIterable('abc'); 
// a
// b
// c
複製代碼

文章的末尾

一些參考文章

一些悄悄話

嗚嗚嗚,數組的方法終於幹完了。

若是你看完了那真的很不錯,我也是斷斷續續寫了兩天。

看完了以後是不是真理解記住了呢?若是沒有看懂那就去再認真看一遍吧。看完以後就會發現本身依舊仍是沒有記住...

哼我不再看了!

這實際上是很正常的事情,光看是記不住的,仍是要多用多實踐,斯賓浩的遺忘曲線告訴咱們即便記住了仍是會遺忘的,玲瓏也會常常複習一下本身寫過的文章。

因此建議你們收多實(收)踐(藏)總(此)結(文),您的鼓勵也是我繼續前行的動力~

若是有錯誤的地方還請您在評論區指出。 下篇文章見...
相關文章
相關標籤/搜索