Javascript - 陣列和陣列的方法

boxZhang發表於2019-02-17

學習在於總結,自己總覺得書到用時方恨少。

陣列是javascript程式設計中的重中之重,歸納整理的這些陣列方法,也是希望自己能夠更全面一些的瞭解陣列知識點,某天忘記了,也可以再回頭看看,也希望能和大家一起分享,一起成長。


陣列的基本概念

什麼是陣列

  1. 陣列是一組資料結合而成的有序列表
  2. 陣列是一個物件,用於在單個變數中儲存多個值

陣列的特點

  1. ECMAScript陣列的每一項都可以儲存任意型別的資料(比如:陣列的第一個位置來儲存字串,第二個位置來儲存數值,第三個位置儲存物件)
  2. ECMAScript陣列的大小是可以動態調整的,例如:可以隨著資料的新增自動增長,來容納新增資料
  3. ECMAScript陣列是一塊連續的記憶體空間,以下標來描述空間的位置

建立陣列的方式

  1. Array建構函式的方式

    var arr = new Array(); //建立一個空陣列 []
    var arr = new Array(3); //建立一個length為3的陣列 [undefined, undefined, undefined]
    var arr = new Array("red","yellow","green");	//建立陣列並賦值 ["red", "yellow", "green"]
    複製程式碼
  2. 陣列字面量表示法

    var arr = [];	//建立一個空陣列
    var arr = ["red","yellow","green"];	//建立了一個包含3個字串的陣列
    var arr = [1,2,];	//不要這樣,會建立一個包含2或3項的陣列,出現相容問題
    var arr = [,,,];	//不要這樣,會建立一個包含3或4項的陣列,出現相容問題
    複製程式碼
  3. of方法(ES6方法)

    var arr = Array.of(7);       // 建立陣列並賦值 [7] 
    var arr = Array.of(1, 2, 3); // 建立陣列並賦值 [1, 2, 3]
    複製程式碼

陣列的屬性(length、prototype、 constructor)

  1. length

    length設定或返回陣列中元素的數目。

    length很有特點,它不是隻讀的,可以通過length這個屬性,從陣列的末尾移除項或向陣列中新增新項

    var arr = ["red","yellow","green"];
    arr.length = 2;	//把arr修改為length為2的陣列,即當length屬性被設定得比原來小時,則原先陣列中索引大於或等於length的元素的值全部被丟失。
    console.log(arr[2]);	//undefined
    
    var colors = ["black","white","blue"];
    colors.length = 4;	// 如果將其length設定為大於陣列項數的值,則新增的每一項都會取undefined值,但實際陣列的狀態不會發生變化,仍舊是["black","white","blue"]
    console.log(colors[3]);	//undefined
    複製程式碼
  2. prototype

    prototype 屬性是 object 共有的。

    一般用來給陣列例項新增屬性和方法。

  3. constructor

    表示建立物件的函式。返回對建立此物件的陣列函式的引用。

    說明:constructor 屬性是所有具有 prototype 的物件的成員。constructor 屬性儲存了對構造特定物件例項的函式的引用。

陣列的檢測

  1. instanceof

    instanceof 用來檢測一個例項是否屬於某個類,彌補了typeof不能檢測具體屬於哪個物件的侷限性(也就是說如果一個例項是object型別的,typeof無法分清這個物件是屬於物件中的陣列還是物件中的正則,只能判斷該型別為是一個object)。

    儘管不像 typeof 方法那樣靈活,但是在 typeof 方法返回 "object" 的情況下,instanceof 方法還是很有用的。

    原理:只要在當前例項原型鏈上的物件,我們用其檢測出來的都是true

    注意:但是在類的原型繼承中,我們最後檢測出來的結果未必正確

    var num =10;
    var arr = [1,2,3];
    console.log(num instanceof Number);	//false  因為instanceof不能用於檢測和處理字面量方式建立出來的基本資料型別值
    console.log(arr instanceof Object);	//true
    console.log(arr instanceof Array);	//true
    複製程式碼
  2. constructor

    constructor 建構函式 是函式原型上的屬性,該屬性指向的是建構函式本身

    作用和instsnceof非常相似,與instanceof不同的是,不僅可以處理引用資料型別,還可以處理原始資料型別。

    var num = 10;
    var arr = [1,2,3];
    console.log(num.constructor == Number);	//true
    console.log(arr.constructor == Object);	//false
    console.log(arr.constructor == Array);	//true	由於constructor可以被重寫,所以不能確保一定是陣列
    
    // 侷限性:我們可以把類的原型進行重寫,在重寫的過程中很可能把之前constructor給覆蓋了,這樣檢測出來的結果就是不準確的。例如:
    function Fn() {};
    var f = Fn;
    console.log(f.constructor);  //ƒ Fn() {}
    console.log(f.constructor == Function);  //true
    Fn.prototype = new Array;
    var f = new Fn;
    //f是一個函式,按道理說他的建構函式應該是Function,但是修改其原型鏈後,它的constructor變成了Array.
    console.log(f.constructor);  //ƒ Array() { [native code] }
    console.log(f.constructor == Array);  //true
    複製程式碼
  3. Array.isArray(obj)

    isArray() 方法用於判斷一個物件是否為陣列。效率較高。

    var arr = [1,2,3];
    var isArr = Array.isArray(arr);	
    console.log(isArr);	//true
    複製程式碼
  4. Object.prototype.toString.call()

    原型鏈上的Object物件的toString方法

    Object.prototype.toString的作用是返回當前方法的執行主體(方法中的this)所屬類的詳細資訊,是最全面也是最常用的檢測資料型別的方式。

    var arr = [34,65,1];
    Object.prototype.toString.call(arr) === '[object Array]' //return true
    複製程式碼
    // Object.prototype.toString.call() 用法
    console.log(Object.prototype.toString.call(1));          	//[object Number]
    console.log(Object.prototype.toString.call(/^sf/));        	//[object RegExp]
    console.log(Object.prototype.toString.call("hello"));      	//[object String]
    console.log(Object.prototype.toString.call(true));        	//[object Boolean]
    console.log(Object.prototype.toString.call(null));        	//[object Null]
    console.log(Object.prototype.toString.call(undefined));      //[object Undefined]
    console.log(Object.prototype.toString.call(function() {}));	//[object Function]
    console.log(typeof(Object.prototype.toString.call(function() {})));	//string
    複製程式碼

陣列方法

Javascript - 陣列和陣列的方法

轉換方法( join)

  1. arr.join(separator)

    把陣列構構造成字串,它先把陣列中的每個元素轉換成字串,然後再用 separator 分隔符把它們連結在一起,separator 分隔符預設是逗號 “,”,要想做到無間隔連結,可以使用空字串作為 separator:

    var arr = [1,2,3,4,5]
    arr.join('|');	//"1|2|3|4|5"
    arr.join("");	//12345
     
    //另所有物件有具有的 toLocaleString、toString、valueOf,可以看作是join的特殊用法,不常用
    複製程式碼

棧方法(push、pop)

  1. arr.push(item…)

    將一個或多個新元素新增到陣列結尾,並返回陣列新長度。

    var arr=[1,2,3,4,5];
    arr.push(6);	// 往陣列arr中推入另外一項 6
    console.log(arr);	// [1, 2, 3, 4, 5, 6]
    
    複製程式碼
  2. arr.pop()

    移除最後一個元素並返回該元素值。

    var arr=[1,2,3,4,5];
    var arrItem = arr.pop();	// 移除最後一個元素,並返回該元素的值
    console.log(arrItem);	//5
    console.log(arr);	//[1,2,3,4]
    
    複製程式碼

佇列方法(unshift、shift)

  1. arr.unshift(item)

    在陣列的前端新增任意個項,並返回新的陣列的長度。

    var arr=[1,2,3,4,5];
    arr.unshift(0);	// 往陣列arr中推入另外一項 0
    console.log(arr);	// [0,1, 2, 3, 4, 5]
    複製程式碼
  2. arr.shift()

    從陣列中獲得第一項,並返回該元素值。

    var arr=[1,2,3,4,5];
    var arrItem = arr.shift();	// 移除第一一個元素,並返回該元素的值
    console.log(arrItem);	//1
    console.log(arr);	//[2,3,4,5]
    複製程式碼

重排序方法(reverse、sort)

  1. arr.reverse()

    反轉陣列順序。

    var arr = [2,3,1,5,4];
    arr.reverse();
    console.log(arr);	// [4, 5, 1, 3, 2]
    複製程式碼
  2. arr.sort()

    重新排列陣列順序,預設升序。

    //
    var arr = [20,3,12,1,5,4];
    arr.sort(Fn);
    console.log(arr);	// [1, 12, 20, 3, 4, 5],可見單純的使用sort並沒有達到理想的升序結果
    
    var arr = [20,3,12,1,5,4];
    arr.sort((a, b) => (a - b)); 	// (6) [1, 3, 4, 5, 12, 20]
     
    複製程式碼

操作方法(concat、slice、splice、 copyWithin、 fill)

  1. arr.concat(item) 不影響原始陣列

    concat()方法會基於當前陣列中的所有項建立一個新陣列,也就是concat()方法會先建立當前陣列一個副本,然後將接收到的引數新增到這個副本的末尾,最後返回新構建的陣列。

    var colors = ["red","green","blue"];
    var colors2 = colors.concat("yellow",["black","brown"]);
    console.log(colors);	//["red", "green", "blue"]
    console.log(colors2);	//["red", "green", "blue", "yellow", "black", "brown"]
    複製程式碼
  2. arr.slice(start, end) 不影響原始陣列

    slice()方法基於當前陣列中的一個或多個項建立一個新陣列。

    slice()方法可以接受一個或兩個引數,即要返回項的起始(包括起始位置項)和結束位置(不包括結束位置項)。

    字串也有個同名方法 string.slice。

    var colors = ["red", "green", "blue", "yellow", "black", "brown"];
    var colors1 = colors.slice(1);		//擷取從colors[1]到最後一項的,返回新陣列
    var colors2 = colors.slice(1,4);	//擷取從colors[1]到colors[3],返回新陣列
    var colors3 = colors.slice(-5,-2);	// 此種情況,如果結束位置小於起始位置,則返回空陣列
    console.log(colors);	// ["red", "green", "blue", "yellow", "black", "brown"]
    console.log(colors1);	// ["green", "blue", "yellow", "black", "brown"]
    console.log(colors2);	// ["green", "blue", "yellow"]
    console.log(colors3);	// ["green", "blue", "yellow"]  
    複製程式碼
  3. arr.splice(start, deleteCount, item…) 影響原始陣列

    splice()方法從 arr 中移除一個或多個元素,並將新的 item 插入至移除元素的開始位置, 引數 start 是移除元素的開始位置,deleteCount 是要移除的元素的個數,item 是要被插入的元素。它返回一個包含被移除元素的陣列。

    // 刪除
    var colors1 = ["red", "green", "blue", "yellow", "black", "brown"];
    var removed = colors1.splice(0,1);	//從第0個開始,移除1項,並返回移除的內容
    console.log(colors1);	//(5) ["green", "blue", "yellow", "black", "brown"]
    console.log(removed);	//["red"]
    
    // 插入
    var colors2 = ["red", "green", "blue", "yellow", "black", "brown"];
    var removed = colors2.splice(1,0,"orange","purple");	//從第1項開始,移除0項,插入"orange","purple",並返回移除的內容
    console.log(colors2);	//(8) ["red", "orange", "purple", "green", "blue", "yellow", "black", "brown"]
    console.log(removed);	//[]
    
    // 替換
    var colors3 = ["red", "green", "blue", "yellow", "black", "brown"];
    var removed = colors3.splice(1,1,"orange","purple");	//從第1項開始,移除1項,插入"orange","purple",並返回移除的內容
    console.log(colors3);	//(7) ["red", "orange", "purple", "blue", "yellow", "black", "brown"]
    console.log(removed);	//["green"]
    複製程式碼
  4. arr.copyWithin(target, start, end) 影響原始陣列

    arr.copyWithin()該方法複製陣列的一部分到同一陣列中的另一個位置(會覆蓋原成員),並返回修改後的陣列。使用這個方法,會修改當前陣列。

    引數 target 為開始替換資料的位置,若 target 大於等於 arr.length,將會不發生拷貝。

    start 是可選引數,為開始讀取資料的位置,預設為0。

    end 是可選引數,為停止讀取資料的位置,預設為 arr.length。

    var arr = [1, 2, 3, 4, 5];
    arr.copyWithin(0, 3);	// 將從3號位直到陣列結束的成員(4和5),複製到從0號位開始的位置,結果覆蓋了原來的1和2。
    console.log(arr);	// [4, 5, 3, 4, 5]
    複製程式碼
  5. arr.fill(value,start,end) 影響原始陣列

    該方法使用給定值填充一個陣列,引數 value 是用來填充陣列的值。start 是可選引數,為填充開始位置,預設為 0。end 是可選引數,為填充的結束位置,預設為 arr.length。

    [1, 2, 3].fill(4)            // [4, 4, 4]
    [1, 2, 3].fill(4, 1 , 2)            // [1, 4, 3]
    複製程式碼

位置方法(indexOf、 lastIndexOf、includes)

  1. arr.indexOf(searchElement, start)

    該方法返回要查詢的項在陣列中的位置,如果沒找到返回 -1。

    接受兩個引數,searchElement 是要查詢的項,start 是查詢起始位置的索引,預設是0。

    var numbers = [1,2,3,4,5,4,3,2,1];
    console.log(numbers.indexOf(2));	//1	查詢2,從第0項開始,往後找
    console.log(numbers.indexOf(2,3));	//7	查詢2,從第3項開始,包括第三項,往後找
    console.log(numbers.indexOf(8,3));	//-1	查詢8,從第3項開始
    複製程式碼
  2. arr.lastIndexOf(searchElement, start)

    從 start 位置開始向前查詢,start 預設值為 arr.length – 1。

    注意該方法在比較查詢項與陣列中每一項時,會使用全等操作符,也就是要求查詢的項必須嚴格相等。

    var numbers = [1,2,3,4,5,4,3,2,1];
    console.log(numbers.lastIndexOf(2));	//7	查詢2,從最後一項開始,往前找
    console.log(numbers.lastIndexOf(2,3));	//1	查詢2,從第3項開始,包括第三項,往前找
    複製程式碼
  3. arr.includes(searchElement, fromIndex)

    var numbers = [1,2,3,4,5,4,3,2,1];
    console.log(numbers.includes(2));	//true	查詢2,從第0項開始,如果有,則返回true,否則返回false
    console.log(numbers.includes(4,6));	//false	查詢4,從第76項開始,如果有,則返回true,否則返回false
    複製程式碼

迭代方法(every、 some、 filter、 forEach、 map、 find、 findIndex、entries、keys、values)

每個迭代方法都接收兩個引數:1、要在每一項上執行的函式( callback);2、執行該函式的作用域物件(thisArg)——影響this值。

傳入這些方法中的函式會接收三個引數:1、陣列項的值;2、該項在陣列中的位置;3、陣列物件本身

  1. arr.every(callback,thisArg)

    對陣列中的每一項執行給定函式,如果該函式對每一項都返回true,則返回true。

    var numbers = [1,2,3,4,5,4,3,2,1];
    var everyItem = numbers.every((item,index,array) => (item>2));
    console.log(everyItem);	//false
    複製程式碼
  2. arr.some(callback, thisArg)

    some()和every()很像,some()對陣列中的每一項執行給定函式,如果該函式對某一項返回 true,則返回 true。

    var numbers = [1,2,3,4,5,4,3,2,1];
    var everyItem = numbers.some((item,index,array) => (item>2));
    console.log(everyItem);	//true
    複製程式碼
  3. arr.filter(callback, thisArg)

    對陣列中的每一項執行給定函式,返回該函式會返回 true 的項組成的陣列。

    var numbers = [1,2,3,4,5,4,3,2,1];
    var everyItem = numbers.filter((item,index,array) => (item>2));
    console.log(numbers);	//(9) [1, 2, 3, 4, 5, 4, 3, 2, 1]
    console.log(everyItem);	//(5) [3, 4, 5, 4, 3]
    複製程式碼
  4. arr.forEach(callback)

    對陣列中的每一項執行給定函式,這個方法沒有返回值。本質上與使用 for 迴圈迭代陣列一樣。

    var numbers = [1,2,3,4,5,4,3,2,1];
    var everyItem = numbers.forEach((item,index,array) => {   
        // 執行某些操作
    });
    複製程式碼
  5. arr.map(callback)

    對陣列中的每一項執行給定函式,返回每次函式呼叫組成的陣列。

    var numbers = [1,2,3,4,5,4,3,2,1];
    var everyItem = numbers.map((item,index,array) => item*2);
    console.log(numbers);	//(9) [1, 2, 3, 4, 5, 4, 3, 2, 1]
    console.log(everyItem);	//(9) [2, 4, 6, 8, 10, 8, 6, 4, 2]
    複製程式碼
  6. arr.find(callback, thisArg)

    該方法對陣列所有成員依次執行 callback 函式,直到找出第一個返回值為 true 的成員,然後返回該成員。如果沒有符合條件的成員,則返回 undefined。

    [1, 4, -5, 10].find((v, i, arr) => v < 0);	// -5
    複製程式碼
  7. arr.findIndex(callback, thisArg)

    該方法與 arr.find() 類似,對陣列中的成員依次執行 callback 函式,直至找到第一個返回值為 true 的成員,然後返回該成員的索引。如果沒有符合條件的成員,則返回 -1。

    [1, 5, 10, 15].findIndex((v, i , arr)=>{
        return v > 9
    })	//2
    複製程式碼
  8. arr.entries()arr.keys()arr.values()

    這三個方法都返回一個新的Array Iterator物件,可以用for...of迴圈進行遍歷,區別是keys()是對鍵名的遍歷、values()是對鍵值的遍歷,entries()是對鍵值對的遍歷。

    for (let index of ['a', 'b'].keys()) { console.log(index); }
    // 0
    // 1
     
    for (let elem of ['a', 'b'].values()) { console.log(elem) ;}
    // 'a'
    // 'b'
     
    for (let [index, elem] of ['a', 'b'].entries()) { console.log(index, elem);}
    // 0 "a"
    // 1 "b"
     
    var arr = ["a", "b";
    var iterator = arr.entries(); // undefined
     
    console.log(iterator); // Array Iterator {}
    console.log(iterator.next().value);  // [0, "a"]
    console.log(iterator.next().value);  // [1, "b"]
    複製程式碼

歸併方法(reduce、 reduceRight)

陣列的reduce()和reduceRight()這兩個方法都會迭代陣列的所有項,然後構建一個最終返回的值。

他們都接收4個引數:1、前一個值;2、當前值;3、項的索引;4、陣列物件

  1. arr.reduce(callback, intialValue)

    reduce()方法從陣列的第一項開始,逐個遍歷到最後。

    var values = [1,2,3,4,5];
    var sum = values.reduce((prev,cur,index,array) => {
        console.log(prev,cur)
            // 1 2
    	// 3 3
    	// 6 4
    	// 10 5
        return prev + cur
    })
    console.log(sum);	//15
    複製程式碼
  2. arr.reduceRight(callback,intiaValue)

    reduceRight()方法從陣列的最後一項開始,逐個遍歷到第一項。

    var values = [1,2,3,4,5];
    var sum = values.reduceRight((prev,cur,index,array) => {
        console.log(prev,cur);	
            //5 4
    	// 9 3
    	// 12 2
    	// 14 1
        return prev + cur
    })
    console.log(sum);	//15
    複製程式碼

參考文章


如若發現文中紕漏請留言,歡迎大家糾錯,我們一起成長。

相關文章