JavaScript數組(ES5&&ES6)

不管什麼編程語言,數組老是用的最多的引用數據類型之一。JS中的數組有些特殊,它不像Java那種強類型語言那樣,一個數組只能存放一種類型的數據。JavaScript容許數組中的每一項的數據類型不一樣。、編程

本文分九個層面對JavaScript數組的功能及用法作一個簡單的介紹。數組

建立

數組的建立無非有兩種方式:
構造函數:瀏覽器

var arr1 = new Array(1,2,3,4);    // [1,2,3,4]
var arr2 = new Array(2);            // [,,,]

字面量:app

var arr1 = [1,2,3,4];

如上,構造函數Array()在傳入一個數值做爲參數時,這個數值是數組的長度,顯然存在歧義,ES6中的Array.of()方法完善了這一點。
Array.of(1, 2, 3, 4); // [1, 2, 3, 4]
Array.of(2); // [2]框架

固然,絕大數狀況都是使用字面量的形式去建立數組的。編程語言

讀寫

對數組進行讀寫,最簡單的莫過於函數

var arr = [1, 2, 3, 4];
arr[1];                   // 2
arr[1] = 5;

另外,數組的length屬性是可寫的,改變length值也會改變數組:this

arr.length = 5; // [1, 2, 3, 4,]
arr[4];         // undefined

利用length值還能夠在數組末尾新增項:code

arr[arr.length] = 7;  // 數組最後一項的index爲 length - 1

複雜一點的讀寫方式有:push()、pop()、shift()、unshift()
push()、pop()使得數組能夠做爲棧的一種實現,push()能夠接受任意數量的參數,並將其添加至數組尾部返回修改後的數組長度,pop()彈出並返回數組最後一個元素。shift()、push()使數組能夠做爲隊列的一種實現,shift()將數組第一個元素彈出並返回。而unshift()在數組頭部添加任意數量的元素並返回長度。對象

檢測

檢測一個變量是否爲數組類型,最直接的方法:

target instanceof Array

這種方法問題在於若是網頁中有多個框架,即存在多個版本的Array構造函數,不一樣框架的數組實例檢測起來就會失敗,但這種狀況畢竟不常見。
另外就是

Array.isArray(target);

這個API的問題在於過老版本的瀏覽器不支持ES5,但也不足爲道。

檢測數組中是否存在某個值,在ES5中每每經過indexOf()實現,但ES6新增了includes()方法,彌補了arr.indexOf(value) === -1;在語義化和忽略了NaN的問題。

var arr = [1, 2, 3, 4, NaN];
arr.includes(NaN);      // true

轉換

將數組轉換爲字符串,默認的方法有toString(),toLocalString(),valueOf(),以上三種方法都是對數組的每一項調用該方法,而後用逗號鏈接這些項;當須要用其餘符號鏈接每一項時,就須要用到join()方法:

var arr = [1, 2, 3, 4, 5];
arr.join('*');  // 1*2*3*4*5

將數組轉換爲參數列表:使用的是ES6的擴展運算符...,這在函數調用的時候十分有用

function add(x, y, z) {
    return x + y + z;
}

add(...[1, 2, 3]);   // 6

能夠利用這一點對一些只接受參數列表的函數傳遞數組,從而實現某種需求,如求數組中的最大值:

var arr = [1, 2, 3, 4, 5];

// ES5
Math.max().apply(null, arr);

// ES6
Math.max(...arr);

將其餘數據類型(類數組對象、可遍歷對象(如arguments對象,NodeList對象))轉換爲數組:能夠用擴展運算符,也能夠用Array.from()。
二者的區別在於擴展運算符調用的是目標對象的iterator接口,因此...只能將可遍歷對象轉換爲數組,而Array.from()還能夠將類數組對象,即擁有length屬性的對象轉換爲數組。另外Array.from()還可接受第二個參數:做用相似於map函數;第三個參數:第二個參數中的this。

不管是擴展運算符仍是Array.from(),在將字符串轉換爲數組時都會將32位Unicode字符正確識別爲一個字符,能夠利用這一點來正確讀取字符串的長度。

排序

數組實例有兩個方法能夠對數組排序,分別是reverse() 和 sort()。
reverse()僅僅將數組的順序反轉,而若是簡單地調用sort(),不管數組的每一項爲什麼值,都會將其轉換爲字符串比較,就會出現奇怪的現象:

var arr = [2, 10, 5, 4];
arr.reverse();  // [4, 5, 10, 2]
arr.sort();     // [10, 2, 4, 5]

這是由於字符串比較的是對應位置的Unicode值,由於1在2前面因此10比2小。這樣顯然是不合理的,須要向sort傳入排序規則,如:

var arr = [2, 10, 5, 4];
arr.sort(function(curr, next) {
    if (curr < next) {
        return -1;
    } else if (curr > next) {
        return 1;
    } else {
        return 0;
    }
});
arr         // [2, 4, 5, 10]

由於arr的每一項都是數值,能夠寫成

arr.sort(function(curr, next) {
    return curr - next;
});

操做

將多個數組或者參數拼入已有的數組————concat(item1, arr, item2...)
concat接收任意多個參數,能夠是數組或者其餘類型,返回一個新的數組。

// concat不會改變原數組
var arr = [1, 2, 3, 4];
var arr1 = arr.concat(5, [6, 7]);
arr1;   // [1, 2, 3, 4, 5, 6, 7]

取出數組中某一段————slice()
slice接收一個或兩個參數,接收一個參數時返回這個參數表明的位置到數組末尾的段,接收兩個參數時返回兩個參數之間的段,"包括頭不包括尾。"

// slice也不會改變原數組
var arr = [1, 2, 3, 4];
var arr1 = arr.slice(0, 3);
arr1;       // [1, 2, 3]

刪除、插入、替換數組中的項————splice(start, delMount, ...replace)
splice的返回值老是刪除的項

// splice會改變原數組
var arr = [1, 2, 3, 4];

// 刪除 
arr.splice(1, 1);       // [2]
arr;                    // [1, 3, 4]

// 插入
arr.splice(1, 0, 2, 5);
arr;                    // [1, 2, 5, 3, 4]

// 替換
arr.splice(2, 1, 8);    // [5]
arr;                    // [1, 2, 8, 3, 4]

數組內部替換————copyWithin(target, start, end) ES6
此方法返回的是修改後的數組

// copyWithin會改變原數組
var arr = [1, 2, 3, 4, 5];
arr.copyWithin(0, 3);   // [4, 5, 3, 4, 5]

這裏省略了end參數,默認爲到數組結尾

填充數組————fill(item, start, end)

var arr = [1, 2, 3, 4, 5];
arr.fill(7);
arr;            // [7, 7, 7, 7, 7]
arr.fill(8, 0, 2);
arr;            // [8, 8, 7, 7, 7]

位置

查找指定元素在數組中的位置————indexOf(item, start)、lastIndexOf(item, start)

// 若數組中無該元素則返回-1, 此處比較機制爲全等===
var arr = [1, 2, 3, 4, 5, 2];
arr.indexOf(2);         // 1
arr.indexOf(2, 2);      // 5

查找符合條件的元素在數組中的位置————findIndex(func(value, index, arr)) ES6

var arr = [1, 2, 3, 4, 5];
arr.findIndex(function(value) {
    return value > 3;
});                 // 3

迭代

every、filter、forEach、some、map、find(ES6)
迭代方法傳入的都是一個函數:

function(value, index, arr) {
 if (......) {
    // 符合條件
    return true
 }        
}

every: 數組全部項都符合條件時返回true;
some: 數組中任意一項符合條件就返回true;
filter: 返回數組中符合條件的項組成的數組;
forEach: 對數組全部項執行操做,不返回任何值;
map: 對數組每一項執行操做,返回由函數返回值構成的數組;
find: 返回數組中第一個符合條件的項;

Reduce

reduce(function(prev, curr, index, array), initValue),reduce從數組第一項開始執行參數中的函數,其返回值做爲第二項的prev,第二個參數可選,指定prev的初始值

var arr = [1, 2, 3, 4];
arr.reduce(function(prev, cur) {
    return prev + cur;
}); // 10

reduceRight()是從數組末尾開始執行的,用法與reduce一致。

相關文章
相關標籤/搜索