1. 程式人生 > 實用技巧 >JavaScript中Array的常用方法

JavaScript中Array的常用方法

ECMAScript陣列中每個槽位可以儲存任意型別的資料。

ECMAScript中陣列是動態大小的,會隨著資料新增而自動增長。

建立陣列

(1)使用Array建構函式(可省略new操作符)

傳1個引數:number型別時代表初始length,其他型別時建立一個包含該元素的陣列

傳多個引數:建立一個包含這些元素的陣列

let colors = new Array()

(2)使用陣列字面量

使用陣列字面量表示法建立陣列不會呼叫Array建構函式

let colors = ['red', 'blue', 'green']

(3)使用ES6新增靜態方法Array.from(),引數:(類陣列物件,可選的對映函式引數)

Array.from('Matt')    // ['M', 'a', 't', 't']
const m = new Map().set(1, 2)
                   .set(3, 4)
Array.from(m)
// [[1, 2], [3, 4]]
const a = [1, 2, 3, 4]
Array.from(a, x => x**2)    // [1, 4, 6, 9]

(4)使用ES6新增靜態方法Array.of(),引數:(元素1, 元素2, 元素3, ...)

Array.of(1, 2, 3, 4)    // [1, 2, 3, 4]

陣列空位

使用陣列字面量時,可以使用一串逗號來建立空位

ES6新增方法普遍將這些空位當成存在的元素,值為undefined

ES6之前的方法會忽略這個空位,具體的行為因方法而異

(避免使用陣列空位,可以顯式地用undefined值代替)

const options = [,,,,,]    // 建立包含5個元素的陣列
console.log(options.length)    // 5

const options = [1,,,,5]

// map()會跳過空位置
options.map(() => 6)    // [6, undefined, undefined, undefined, 6]
// join()視空位置為空字串 options.join('-') // '1----5'

陣列索引

要取得或設定陣列的值,需要使用中括號並提供相應值的數字索引

let colors = ['red', 'blue', 'green']
console.log(colors[0])    // 'red'
colors[2] = 'black'    // 修改第3項
colors[3] = 'brown'    // 新增第4項

設定超過陣列最大索引的索引,陣列長度會自動擴容到該索引值加1

通過修改length屬性,可以從陣列末尾刪除或新增元素

let colors = ['red', 'blue', 'green']
colors[3] = 'black'
console.log(colors.length)    // 4

colors.length = 3
console.log(colors)    // ['red', 'blue', 'green']

colors.length = 4
console.log(colors)    // ['red', 'blue', 'green', undefined]

使用length屬性可以方便地向陣列末尾新增元素

length屬性會自動更新

let colors = ['red', 'blue', 'green']
colors[colors.length] = 'black'   // 新增一種顏色(位置3)       
colors[colors.length] = 'brown'   // 再新增一種顏色(位置4)

檢測陣列

只有一個全域性執行上下文

if (value instanceof Array) {
    // 運算元組
}

多個全域性執行上下文

if (Array.isArray(value)) {
    // 運算元組
}

迭代器方法(ES6)

(1)keys()返回陣列索引的迭代器

const a = ['foo', 'bar', 'baz', 'qux']
Array.from(a.keys())    // [0, 1, 2, 3]

(2)values()返回陣列元素的迭代器

const a = ['foo', 'bar', 'baz', 'qux']
Array.from(a.values())    // ['foo', 'bar', 'baz', 'qux']

(3)entries()返回索引/值對的迭代器

const a = ['foo', 'bar', 'baz', 'qux']
Array.from(a.entries())    // [[0, 'foo'], [1, 'bar'], [2, 'baz'], [3, 'qux']]

使用ES6解構在迴圈中拆分鍵/值對

const a = ['foo', 'bar', 'baz', 'qux']

for (const [idx, element] of a.entries()) {
    console.log(idx)
    console.log(element)
}

複製和填充(ES6)

批量複製方法copyWithin()和填充陣列方法fill()

需要指定既有陣列例項上的一個範圍,包含開始索引,不包含結束索引,不會改變陣列大小

(1)填充陣列方法fill(),向一個已有的陣列中插入全部或部分相同的值

引數:(填充值, 開始索引(可選), 結束索引(可選)),負值索引從陣列末尾開始計算(陣列長度加上負值索引得到的正索引)

const zeroes = [0, 0, 0, 0, 0]

// 用5填充整個陣列
zeroes.fill(5)
console.log(zeroes)    // [5, 5, 5, 5, 5]
zeroes.fill(0)         // 重置

// 用6填充索引大於等於3的元素
zeroes.fill(6, 3)
console.log(zeroes)    // [0, 0, 0, 6, 6]
zeroes.fill(0)         // 重置

// 用7填充索引大於等於1且小於3的元素
zeroes.fill(7, 1, 3)
console.log(zeroes)    // [0, 7, 7, 0, 0]
zeroes.fill(0)         // 重置

// 用8填充索引大於等於1且小於4的元素
// (-4 + zeroes.length = 1)
// (-1 + zeroes.length = 4)
zeroes.fill(8, -4, -1)
console.log(zeroes)    // [0, 8, 8, 8, 0]

fill()靜默忽略超出陣列邊界、零長度及方向相反的索引範圍

const zeroes = [0, 0, 0, 0, 0]

// 索引過低,忽略
zeroes.fill(1, -10, -6)
console.log(zeroes)    // [0, 0, 0, 0, 0]

// 索引過高,忽略
zeroes.fill(1, 10, 15)
console.log(zeroes)    // [0, 0, 0, 0, 0]

// 索引反向,忽略
zeroes.fill(2, 4, 2)
console.log(zeroes)    // [0, 0, 0, 0, 0]

// 索引部分可用,填充可用部分
zeroes.fill(4, 3, 10)
console.log(zeroes)    // [0, 0, 0, 4, 4]

(2)批量複製方法copyWithin(),按照指定範圍潛複製陣列中的部分內容,將它們插入到指定索引開始的位置

引數:(插入位置開始索引, 複製內容開始索引(可選), 複製內容結束索引(可選))

let ints,
    reset = () => ints = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
reset()

// 從ints中複製索引0開始的內容,插入到索引5開始的位置
// 在源索引或目標索引到達陣列邊界時停止
ints.copyWithin(5)
console.log(ints)    // [0, 1, 2, 3, 4, 0, 1, 2, 3, 4]
reset()

// 從ints中複製索引5開始的內容,插入到索引0開始的位置
ints.copyWithin(0, 5)
console.log(ints)    // [5, 6, 7, 8, 9, 5, 6, 7, 8, 9]
reset()

// 從ints中複製索引0開始到索引3結束的內容
// 插入到索引4開始的位置
ints.copyWithin(4, 0, 3)
console.log(ints)    // [0, 1, 2, 3, 0, 1, 2, 7, 8, 9]
reset()

// JavaScript引擎在插值前會完整複製範圍內的值
// 因此複製期間不存在重寫的風險
ints.copyWithin(2, 0, 6)
console.log(ints)    // [0, 1, 0, 1, 2, 3, 4, 5, 8, 9]
reset()

// 支援負值索引,與fill()相對於陣列末尾計算正向索引的過程是一樣的
ints.copyWithin(-4, -7, -3)
console.log(ints)    // [0, 1, 2, 3, 4, 5, 3, 4, 5, 6]

copyWithin()靜默忽略超出陣列邊界、零長度及方向相反的索引範圍

let ints,
    reset = () => ints = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
reset()

// 索引過低,忽略
ints.copyWithin(1, -15, -12)
console.log(ints)    // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
reset()

// 索引過高,忽略
ints.copyWithin(1, 12, 15)
console.log(ints)    // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
reset()

// 索引反向,忽略
ints.copyWithin(2, 4, 2)
console.log(ints)    // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
reset()

// 索引部分可用,複製、填充可用部分
ints.copyWithin(4, 7, 10)
console.log(ints)    // [0, 1, 2, 3, 7, 8, 9, 7, 8, 9]

轉換方法

(1)valueOf()方法返回陣列本身

let colors = ['red', 'green', 'blue']

console.log(colors)    // ['red', 'green', 'blue']
console.log(colors.valueOf())    // ['red', 'green', 'blue']

(2)toString()方法返回由陣列中每個值的等效字串拼接而成的一個逗號分割的字串(對陣列的每個值會呼叫其toString()方法)

let colors = ['red', 'green', 'blue']

console.log(colors)    // ['red', 'green', 'blue']
console.log(colors.toString())    // red,green,blue

(3)toLocaleString()方法返回一個逗號分割的陣列值的字串(對陣列中的每個值會呼叫其toLocaleString()方法)

let person1 = {
    toString() {
        return 'Nicholas'
    },

    toLocaleString() {
        return 'Nikolaos'
    }
}

let person2 = {
    toString() {
        return 'Greg'
    },

    toLocaleString() {
        return 'Grigorios'
    }
}

let people = [person1, person2]
console.log(people.toString())        // Nicholas,Greg
console.log(people.toLocaleString())    // Nikolaos,Grigorios

(4)join()方法接收一個引數,即字串分隔符,返回包含所有項的字串

不給join()傳入任何引數或者傳入undefined,則仍使用逗號作為分隔符

let colors = ['red', 'green', 'blue']
console.log(colors.join(','))     // red,green,blue
console.log(colors.join('||'))    // red||green||blue

如果陣列中某一項是nullundefined,則在join(),toLocaleString(),toString()和valueOf()返回的結果中會以空字串表示

棧方法(後進先出,LIFO,Last-In-First-Out)

(1)插入(稱為推入,push),push()方法接收任意數量的引數,並將它們新增到陣列末尾,返回陣列的最新長度

let colors = new Array()
let count = colors.push('red', 'green')
console.log(colors)    // ['red', 'green']
console.log(count)     // 2

(2)刪除(稱為彈出,pop),pop()方法用於刪除陣列的最後一項,同時減少陣列的length值,返回被刪除的項

let colors = ['red', 'green']
let item = colors.pop()
console.log(item)           // green
console.log(colors.length)  // 1

佇列方法(先進先出,FIFO,First-In-First-Out)

(1)shift()方法刪除陣列的第一項並返回它,陣列長度減1

let colors = ['red', 'green']
let item = colors.shift()
console.log(item)           // red
console.log(colors.length)  // 1

使用shift()方法和push()方法可以把陣列當成佇列來使用

let colors = new Array()
colors.push('red', 'green')
console.log(colors)     // ['red', 'green']

colors.push('black')
let item = colors.shift()
console.log(item)       // red
console.log(colors)     // ['green', 'black']

(2)unshift()方法在陣列開頭新增任意多個值,返回新的陣列長度

let colors = new Array()
colors.unshift('red', 'green')
console.log(colors)     // ['red', 'green']

colors.unshift('black')
console.log(colors)     // ['black', 'red', 'green']

使用unshift()方法和pop()方法可以在相反方向上模擬佇列

let colors = new Array()
colors.unshift('red', 'green')
console.log(colors)     // ['red', 'green']

colors.unshift('black')
let item = colors.pop()
console.log(item)       // green
console.log(colors)     // ['black', 'red']

排序方法

(1)reverse()方法將陣列元素反向排列

let values = [1, 2, 3, 4, 5]
values.reverse()
console.log(values)     // [5, 4, 3, 2, 1]

(2)sort()方法會按照升序重新排列陣列元素,sort()方法會在每一項上呼叫String()轉型函式,然後比較字串來決定順序

let values = [0, 1, 5, 10, 15]
values.sort()
console.log(values)     // [0, 1, 10, 15, 5]

sort()方法可以接收一個比較函式,用於判斷哪個值應該排在前面

比較函式接收兩個引數,如果第一個引數應該排在第二個引數前面,就返回負值;如果兩個引數相等,就返回0;如果第一個引數應該排在第二個引數後面,就返回正值

function compare(val1, val2) {
    if (val1 < val2) {
        return -1
    } else if (val1 > val2) {
        return 1
    } else {
        return 0
    }
}

let values = [0, 1, 5, 10, 15]
values.sort(compare)
console.log(values)     // [0, 1, 5, 10, 15]

產生降序效果,只需把返回值交換一下即可

function compare(val1, val2) {
    if (val1 < val2) {
        return 1
    } else if (val1 > val2) {
        return -1
    } else {
        return 0
    }
}

比較函式簡寫為箭頭函式

let values = [0, 1, 5, 10, 15]
values.sort((a, b) => a < b ? 1 : a > b ? -1 : 0)
console.log(values)     // [15, 10, 5, 1, 0]

如果陣列的元素是數值,或者其valueOf()方法返回數值的物件(如Date物件),比較函式可以簡寫

function compare(val1, val2) {
    return val2 - val1
}