天天看點

詳解JavaScript的數組,JS數組方法大全

什麼是數組

  • 數組是值得有序集合,每個值叫做一個元素,而每個元素在數組中有一個位置,以數字表示,稱為索引。
  • js的數組是無類型的,數組元素可以是任意類型,同一個數組中的不同元素可能是對象或數組。
  • 數組元素的索引不一定要連續,元素之間可以有空隙,叫做稀疏數組 。
  • 每個數組都具有一個length屬性。
  • 針對非稀疏數組,length屬性就是數組元素的個數,針對稀疏數組,元素的length屬性比所有元素的索引要大。

數組的方法詳解

使用數組直接量建立數組,推薦使用這種方式,性能更高

var arr1 = [] 
var arr2 = [1, 3, 45]
var arr3 = [1, 'aa', true,] // 有三個不同資料類型的數組,最後一個逗号為結尾的逗号      

調用構造函數Array()建立數組 不推薦使用這種方式

var a = new Array() // [] 調用時沒有參數
var b = new Array(10) // 調用時有一個數值參數,它指定長度
var c = new Array(1, 2, 3) // [1, 2, 3] 顯式指定兩個或多個數組元素或者數組的一個非數值元素
var d = new Array('22') // ['22'] 如果傳入一個非數值的參數或者參數個數大于1,則表示建立一個包含指定元素的數組      

數組元素的讀和寫

使用[]操作符來通路數組中的一個元素

var c = [0, , 2]
console.log(c[0]) // 0 
console.log(c[1]) // undefined 
console.log(c[2]) // 2 
console.log(c[3]) // undefined
c[1] = 3
console.log(c) // [0, 3, 2]
c[5] = 6
console.log(c) // [0, 3, 2, empty × 2, 6]      

數組的長度

每個數組都有一個 length 屬性,針對非稀疏數組,length 屬性值代表數組中元素的個數,其值比數組中最大的索引大一。當數組是稀疏時,length 屬性值會大于元素個數。數組的長度會大于每一個元素的索引值。

var c = [0, , 2]
c.length // =>3 稀疏數組,最大索引值為2,數組長度為3      

設定 length 屬性為一個小于目前數組長度的非負整數 n 時,目前數組中的那些索引值大于等于 n 的元素将從數組中删除。同時可以将 length 屬性設定為大于目前長度的值,實際不會像數組中添加元素,它隻是在數組尾部建立一個空的區域。

詳解JavaScript的數組,JS數組方法大全

數組也是對象

數組通過數字進行索引,但有趣的是它們也是對象,是以也可以包含字元串鍵值和屬性 (但這些并不計算在數組長度内)

var a = []
a[0] = 1
a['foobar'] = 2
console.log(a) // [1, foobar: 2]
console.log(a.length) // 1
console.log(a['foobar']) // 2
console.log(a[0]) // 1
console.log(a[1]) // undefined      

這裡有個問題需要特别注意,如果字元串鍵值能夠被強制類型轉換為十進制數字的話,它就會被當作數字索引來處理。

var a = []
a['13'] = 42
a.length // 14      

shift

 删除原數組第一項,并傳回删除元素的值;如果數組為空則傳回undefined 

var a = [1, 2, 3, 4, 5];
var b = a.shift(); 
// a:[2, 3, 4, 5]  b:1      

unshift

将參數添加到原數組開頭,并傳回數組的長度

var a = [1, 2, 3, 4, 5];
var b = a.unshift(-2, -1); 
//a:[-2, -1, 1, 2, 3, 4, 5] b:7      

pop

删除原數組最後一項,并傳回删除元素的值;如果數組為空則傳回undefined

var a = [1, 2, 3, 4, 5];
var b = a.pop();
// a:[1, 2, 3, 4] b:5      

push

将參數添加到原數組末尾,并傳回數組的長度

var a = [1, 2, 3, 4, 5];
var b = a.push(6, 7);
// a:[1, 2, 3, 4, 5, 6, 7] b:7      

concat

将多個數組拼接成一個數組 拼接後數組的元素将按照傳入參數的順序排序 ,不改變原數組,傳回拼接後的數組

var array = [1, 2];
var newArray = array.concat([3, 4], "a", true);
console.log(array); // [1, 2]
console.log(newArray); // [1, 2, 3, 4, "a", true]      

splice(start, deleteCount, val1, val2, ...)

從start位置開始删除deleteCount項,并從該位置起插入val1, val2,...

splice()方法始終都會傳回一個數組,該數組中包含從原始數組中删除的項,如果沒有删除任何項,則傳回一個空數組

var a = [1, 2, 3, 4, 5];
var b = a.splice(2, 2, 7, 8, 9); //a:[1, 2, 7, 8, 9, 5] b:[3, 4]
var b = a.splice(0, 1); // 同shift
a.splice(0, 0, -2, -1); var b = a.length; // 同unshift
var b = a.splice(a.length-1, 1); // 同pop
a.splice(a.length, 0, 6, 7); var b = a.length; // 同push      

reverse

将數組反序

var a = [1, 2, 3, 4, 5];
var b = a.reverse();
// a:[5, 4, 3, 2, 1] b:[5, 4, 3, 2, 1]      

slice(start,end)

傳回從原數組中指定開始下标到結束下标之間的項組成的新數組。在隻有一個參數的情況下, slice()方法傳回從該參數指定位置開始到目前數組末尾的所有項。如果有兩個參數,該方法傳回起始和結束位置之間的項——但不包括結束位置的項。當出現負數時,将負數加上數組長度的值來替換該位置的數(原數組中的倒數第幾個元素開始提取),​

​slice(-2)​

​ 表示提取原數組中的倒數第二個元素到最後一個元素(包含最後一個元素)。

var a = [1, 2, 3, 4, 5];    
var b = a.slice(2, 5); 
// a:[1, 2, 3, 4, 5];  b:[3, 4, 5]      

slice 方法可以用來将一個類數組(Array-like)對象/集合轉換成一個新數組。你隻需将該方法綁定到這個對象上。 一個函數中的arguments就是一個類數組對象的例子

function fxFn () {
    return Array.prototype.slice.call(arguments);
}
var fx = fxFn(1, 2, 3); 
console.log(fx) // [1, 2, 3]      

除了使用 ​

​Array.prototype.slice.call(​

​​

​arguments​

​​

​)​

​​,你也可以簡單的使用 ​

​[].slice.call(arguments)​

​​ 來代替。另外,你可以使用 ​

​bind​

​ 來簡化該過程。

var unboundSlice = Array.prototype.slice;
var slice = Function.prototype.call.bind(unboundSlice);
function fxFn() {
    return slice(arguments);
}
var fx = fxFn(1, 2, 3); 
console.log(fx) // [1, 2, 3]      

join(separator)

 将數組的元素組起一個字元串,以separator為分隔符,省略的話則用預設用逗号為分隔符 

var a = [1, 2, 3, 4, 5];
var b = a.join("|");
// a:[1, 2, 3, 4, 5] b:"1|2|3|4|5"      

sort()

 按升序排列數組項——即最小的值位于最前面,最大的值排在最後面

 在排序時,sort()方法會調用每個數組項的 toString()轉型方法,然後比較得到的字元串,以确定如何排序。即使數組中的每一項都是數值, sort()方法比較的也是字元串,是以會出現以下的這種情況

var arr1 = ["a", "d", "c", "b"];
console.log(arr1.sort()); // ["a", "b", "c", "d"]
arr2 = [13, 24, 51, 3];
console.log(arr2.sort()); // [13, 24, 3, 51]
console.log(arr2); // [13, 24, 3, 51](元數組被改變)      

為了解決上述問題,sort()方法可以接收一個比較函數作為參數,以便我們指定哪個值位于哪個值的前面。比較函數接收兩個參數,如果第一個參數應該位于第二個之前則傳回一個負數,如果兩個參數相等則傳回 0,如果第一個參數應該位于第二個之後則傳回一個正數。以下就是一個簡單的比較函數:

function compare(value1, value2) {
    if (value1 < value2) {
        return -1;
    } else if (value1 > value2) {
        return 1;
    } else {
        return 0;
    }
}
arr2 = [13, 24, 51, 3];
console.log(arr2.sort(compare)); // [3, 13, 24, 51]      

如果需要通過比較函數産生降序排序的結果,隻要交換比較函數傳回的值即可:

function compare(value1, value2) {
    if (value1 < value2) {
        return 1;
    } else if (value1 > value2) {
        return -1;
    } else {
        return 0;
    }
}
arr2 = [13, 24, 51, 3];
console.log(arr2.sort(compare)); // [51, 24, 13, 3]      

indexOf():接收兩個參數:要查找的項和(可選的)表示查找起點位置的索引。其中, 從數組的開頭(位置 0)開始向後查找。 

lastIndexOf:接收兩個參數:要查找的項和(可選的)表示查找起點位置的索引。其中, 從數組的末尾開始向前查找。

這兩個方法都傳回要查找的項在數組中的位置,或者在沒找到的情況下傳回-1。在比較第一個參數與數組中的每一項時,會使用全等操作符。

var array = [1, 2, 3, 4, 5];
var ret = array.indexOf(4);
console.log(array); // [1, 2, 3, 4, 5]
console.log(ret); // 3
console.log(array.indexOf(6)); // -1
console.log(array.lastIndexOf(8)); // -1
console.log(array.lastIndexOf(5)); // 4      

copyWithin(target,staart, end)

淺複制數組的一部分到同一數組中的另一個位置,并傳回它,不會改變原數組的長度。

  • ​target​

    ​​:0 為基底的索引,複制序列到該位置。如果是負數,​

    ​target​

    ​​ 将從末尾開始計算。

    如果​​

    ​target​

    ​​ 大于等于​

    ​arr.length​

    ​​,将會不發生拷貝。如果​

    ​target​

    ​​ 在​

    ​start​

    ​​ 之後,複制的序列将被修改以符合​

    ​arr.length​

    ​。
  • ​start​

    ​​:0 為基底的索引,開始複制元素的起始位置。

    如果​​

    ​start​

    ​​ 被忽略,​

    ​copyWithin​

    ​ 将會從0開始複制。
  • ​end​

    ​​:0 為基底的索引,開始複制元素的結束位置。​

    ​copyWithin​

    ​​ 将會拷貝到該位置,但不包括​

    ​end​

    ​​ 這個位置的元素。

    如果​​

    ​end​

    ​​ 被忽略,​

    ​copyWithin​

    ​​ 方法将會一直複制至數組結尾(預設為​

    ​arr.length​

    ​)。
  • 如果 start 為負,則其指定的索引位置等同于 length+start,length 為數組的長度。end 也是如此。
let numbers = [1, 2, 3, 4, 5];

numbers.copyWithin(-2);
// [1, 2, 3, 1, 2]

numbers.copyWithin(0, 3);
// [4, 5, 3, 4, 5]

numbers.copyWithin(0, 3, 4);
// [4, 2, 3, 4, 5]

numbers.copyWithin(-2, -3, -1);
// [1, 2, 3, 3, 4]

[].copyWithin.call({length: 5, 3: 1}, 0, 3);
// {0: 1, 3: 1, length: 5}

// ES2015 Typed Arrays are subclasses of Array
var i32a = new Int32Array([1, 2, 3, 4, 5]);

i32a.copyWithin(0, 2);
// Int32Array [3, 4, 5, 4, 5]

// On platforms that are not yet ES2015 compliant: 
[].copyWithin.call(new Int32Array([1, 2, 3, 4, 5]), 0, 3, 4);
// Int32Array [4, 2, 3, 4, 5]      

fill(value,start,end)

  • 用一個固定值填充一個數組中從起始索引到終止索引内的全部元素。不包括終止索引。
  • ​value:​

    ​用來填充數組元素的值。
  • ​start​

    ​ :可選,起始索引,預設值為0。
  • ​end​

    ​​ :可選,終止索引,預設值為​

    ​this.length​

    ​。
  • 傳回值:修改後的數組
  • 如果​

    ​start​

    ​​ 是個負數, 則開始索引會被自動計算成為​

    ​length+start​

    ​​, 其中​

    ​length​

    ​​ 是​

    ​this​

    ​​ 對象的​

    ​length ​

    ​​屬性值。如果​

    ​end​

    ​​ 是個負數, 則結束索引會被自動計算成為​

    ​length+end​

    ​。
[1, 2, 3].fill(4);               // [4, 4, 4]
[1, 2, 3].fill(4, 1);            // [1, 4, 4]
[1, 2, 3].fill(4, 1, 2);         // [1, 4, 3]
[1, 2, 3].fill(4, 1, 1);         // [1, 2, 3]
[1, 2, 3].fill(4, 3, 3);         // [1, 2, 3]
[1, 2, 3].fill(4, -3, -2);       // [4, 2, 3]
[1, 2, 3].fill(4, NaN, NaN);     // [1, 2, 3]
[1, 2, 3].fill(4, 3, 5);         // [1, 2, 3]
Array(3).fill(4);                // [4, 4, 4]
[].fill.call({ length: 3 }, 4);  // {0: 4, 1: 4, 2: 4, length: 3}

// Objects by reference.
var arr = Array(3).fill({}) // [{}, {}, {}];
// 需要注意如果fill的參數為引用類型,會導緻都執行都一個引用類型
// 如 arr[0] === arr[1] 為true
arr[0].hi = "hi"; // [{ hi: "hi" }, { hi: "hi" }, { hi: "hi" }]      

includes(valueToFind,fromIndex) 

  • 判斷一個數組是否包含一個指定的值,根據情況,如果包含則傳回 true,否則傳回false。
  • ​valueToFind​

    ​:需要查找的元素值。
  • ​fromIndex​

    ​​:可選,從​

    ​fromIndex​

    ​​ 索引處開始查找​

    ​valueToFind​

    ​​。如果為負值,則按升序從​

    ​array.length + fromIndex​

    ​​ 的索引開始搜 (即使從末尾開始往前跳​

    ​fromIndex​

    ​ 的絕對值個索引,然後往後搜尋)。預設為 0。
  • 如果 fromIndex 為負值,計算出的索引将作為開始搜尋searchElement的位置。如果計算出的索引小于 0,則整個數組都會被搜尋。
[1, 2, 3].includes(3, 3);  // false
[1, 2, 3].includes(3, -1); // true
[1, 2, NaN].includes(NaN); // true

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

arr.includes('a', -100); // true
arr.includes('b', -100); // true
arr.includes('c', -100); // true
arr.includes('a', -2); // false      

作為通用方法的 includes()

(function() {
  console.log([].includes.call(arguments, 'a')); // true
  console.log([].includes.call(arguments, 'd')); // false
})('a','b','c');      

keys() / values() / entries()

傳回一個包含數組中每個索引鍵的Array Iterator對象。索引疊代器會包含那些沒有對應元素的索引

var arr = ["a", , "c"];
var sparseKeys = Object.keys(arr);
console.log(sparseKeys); // ['0', '2']
[...arr1.entries()] // [[0, "a"][1, undefined][2, "c"]]
[...arr1.keys()] // [0, 1, 2]
[...arr1.values()] // ["a", undefined, "c"]      

filter()

  • 建立一個新數組, 其包含通過所提供函數實作的測試的所有元素。
  • 傳回值:一個新的、由通過測試的元素組成的數組,如果沒有任何數組元素通過測試,則傳回空數組。
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var arr2 = arr.filter(function(x, index) {
    return index % 3 === 0 || x >= 8;
}); 
console.log(arr2); //[1, 4, 7, 8, 9, 10]      
var arr = [1 , 3, 4, 7, 12]
var arrTest = arr.filter((item, index, array) => {
    console.log('目前值:' + item, '目前值的索引' + index, '目前數組' + array)
    return item >= 4
})
console.log(arrTest)      
詳解JavaScript的數組,JS數組方法大全

every():判斷數組中每一項都是否滿足條件,隻有所有項都滿足條件,才會傳回true。

var arr = [1, 2, 3, 4, 5];
var arr2 = arr.every(function(x) {
    return x < 10;
}); 
console.log(arr2); //true
var arr3 = arr.every(function(x) {
    return x < 3;
}); 
console.log(arr3); // false      
var arr = [1 , 3, 4, 7, 12]
var arrTest = arr.every((item, index, array) => {
    console.log('目前值:' + item, '目前值的索引' + index, '目前數組' + array)
    return item > 0
})
console.log(arrTest)      
詳解JavaScript的數組,JS數組方法大全

 some():判斷數組中是否存在滿足條件的項,隻要有一項滿足條件,就會傳回true。

var arr = [1, 2, 3, 4, 5];
var arr2 = arr.some(function(x) {
    return x < 3;
}); 
console.log(arr2); //true
var arr3 = arr.some(function(x) {
    return x < 1;
}); 
console.log(arr3); // false      

Array.from()

将僞數組對象(擁有一個 ​

​length​

​ 屬性和若幹索引屬性的任意對象)或疊代對象(可以擷取對象中的元素,如 Map和 Set 等)轉化成真數組,傳回值:一個新的數組

Array.from(arrayLike, mapFn, thisArg)      
  • ​arrayLike ​

    ​想要轉換成數組的僞數組對象或可疊代對象。
  • ​mapFn (可選參數)​

    ​ 如果指定了該參數,新數組中的每個元素會執行該回調函數。
  • ​thisArg (可選參數)​

    ​​ 可選參數,執行回調函數​

    ​mapFn​

    ​​ 時​

    ​this​

    ​ 對象。
Array.from('foo'); 
// ["f", "o", "o"]

=====

let s = new Set(['foo', window]); 
Array.from(s); 
// ["foo", window]

=====

let m = new Map([[1, 2], [2, 4], [4, 8]]);
Array.from(m); 
// [[1, 2], [2, 4], [4, 8]]

const mapper = new Map([['1', 'a'], ['2', 'b']]);
Array.from(mapper.values());
// ['a', 'b'];

Array.from(mapper.keys());
// ['1', '2'];

=====

function f() {
  return Array.from(arguments);
}

f(1, 2, 3); // [1, 2, 3]

=====

Array.from([1, 2, 3], x => x + x);  
// x => x + x代表這是一個函數,隻是省略了其他的定義,這是一種Lambda表達式的寫法
// 箭頭的意思表示從目前數組中取出一個值,然後自加,并将傳回的結果添加到新數組中    
// [2, 4, 6]
Array.from({length: 5}, (v, i) => i);
// [0, 1, 2, 3, 4]      
function combine(){ 
    let arr = [].concat.apply([], arguments);  //沒有去重複的新數組 
    return Array.from(new Set(arr));
} 

var m = [1, 2, 2], n = [2,3,3]; 
console.log(combine(m,n));                     // [1, 2, 3]      

​Array.of()​

​ 

  • 建立一個具有可變數量參數的新數組執行個體,而不考慮參數的數量或類型
  • ​Array.of()​

    ​​ 和​

    ​Array​

    ​​ 構造函數之間的差別在于處理整數參數:​

    ​Array.of(7)​

    ​​ 建立一個具有單個元素 7 的數組,而​

    ​Array(7)​

    ​​ 建立一個長度為7的空數組(注意:這是指一個有7個空位(empty)的數組,而不是由7個​

    ​undefined​

    ​組成的數組)
Array.of(7);       // [7] 
Array.of(1, 2, 3); // [1, 2, 3]
Array.of(undefined); // [undefined]
Array(7);          // [ , , , , , , ]
Array(1, 2, 3);    // [1, 2, 3]      

Array.isArray() 

// 下面的函數調用都傳回 true
Array.isArray([]);
Array.isArray([1]);
Array.isArray(new Array());
Array.isArray(new Array('a', 'b', 'c', 'd'))
// 鮮為人知的事實:其實 Array.prototype 也是一個數組。
Array.isArray(Array.prototype); 

// 下面的函數調用都傳回 false
Array.isArray();
Array.isArray({});
Array.isArray(null);
Array.isArray(undefined);
Array.isArray(17);
Array.isArray('Array');
Array.isArray(true);
Array.isArray(false);
Array.isArray(new Uint8Array(32))
Array.isArray({ __proto__: Array.prototype });      
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
xArray = window.frames[window.frames.length-1].Array;
var arr = new xArray(1,2,3); // [1,2,3]

// Correctly checking for Array
Array.isArray(arr);  // true
// Considered harmful, because doesn't work though iframes
arr instanceof Array; // false      

繼續閱讀