001 Array 類型

《JavaScript 高級(jí)程序設(shè)計(jì)》這本書(shū)被稱為 JavaScript 編程的圣經(jīng),又稱為紅寶書(shū)。記得這本書(shū)是我在剛學(xué)前端那會(huì)和犀牛書(shū)一起購(gòu)買(mǎi)的,這期間斷斷續(xù)續(xù)翻了翻,大部分都處于落灰狀態(tài)。
這本書(shū)很經(jīng)典,關(guān)于 JavaScript 編程的方方面面基本上都講到了,要是能夠通讀一遍,可以省去一些翻文檔和查資料的時(shí)間,這本書(shū)的內(nèi)容也是挺豐盛的,因此我專門(mén)建了一個(gè)文集,用來(lái)做一些讀書(shū)筆記,以在忘記某塊知識(shí)時(shí)能夠回頭翻一翻。

判斷數(shù)組

關(guān)于判斷數(shù)組,這里總結(jié)兩種方式:
1.使用 Object 原型鏈上的 toString 方法判斷:

function isArray(arr){
    return Object.prototype.toString.call(arr).indexOf("Array") !== -1
}

isArray([]) // true
isArray({}) // false

2.使用 Array 對(duì)象上原生的 isArray 方法:

Array.isArray([]) //true
Array.isArray({}) //false

數(shù)組的 toString 方法

調(diào)用數(shù)組的 toString 方法,會(huì)依次調(diào)用數(shù)組每一項(xiàng)的 toString 方法,然后將返回值使用逗號(hào)進(jìn)行拼接:

const arr = [{a:1},[],1,2,"hello"]
arr.toString() // "[object Object],,1,2,hello"

同理,調(diào)用數(shù)組的 toLocaleStringvalueOf 方法時(shí)也會(huì)依次調(diào)用數(shù)組各項(xiàng)元素的 toLocaleStringvalueOf 方法,然后使用逗號(hào)進(jìn)行拼接。
我們也可以修改數(shù)組各項(xiàng)元素的 toString 方法,以取代默認(rèn)結(jié)果:

let ele1 = {
    name:"ele1",
    toString(){
        return "么么噠"
    }
}
let ele2 = {
    name:"ele2",
    toString(){
        return "呵呵噠"
    }
}
const arr = [ele1,ele2]

arr.toString() //"么么噠,呵呵噠"

對(duì)于數(shù)組的 toLocaleStringvalueOf 方法同樣適用。

棧/隊(duì)列方法

我們可以使用數(shù)組來(lái)模擬棧或者隊(duì)列數(shù)據(jù)結(jié)構(gòu)。
棧方法:pushpop

let arr = []
arr.push(1,2)
arr.pop() //2
arr.pop() //1

對(duì)列方法:pushshift

let arr = []
arr.push(1,2)
arr.shift() //1
arr.shift() //2

反向隊(duì)列:unshiftpop

let arr = []
arr.unshift(1,2)
arr.pop() //2
arr.pop() //1

排序方法

1.reverse 方法:
該方法用來(lái)對(duì)數(shù)組進(jìn)行反轉(zhuǎn):

let arr = [1,2,3]
arr.reverse() // [3,2,1]

2.sort 方法
該方法用來(lái)對(duì)數(shù)組進(jìn)行排序,默認(rèn)按照升序排序,并且在排序時(shí)通過(guò)元素的 toString 進(jìn)行位置比較。
因此下面的排序可能不是我們想要的結(jié)果:

let arr = [1,2,10,3,20]
arr.sort() //[1,10,2,20,3]

除此之外,sort 方法可以接受一個(gè)函數(shù)作為參數(shù),用來(lái)自定義排序規(guī)則。
該參數(shù)函數(shù)接受兩個(gè)待比較的元素作為參數(shù),函數(shù)返回值決定了這兩個(gè)元素的排序:

  • 返回值小于 0,升序
  • 返回值大于 0,降序
  • 返回值等于 0,表示這兩個(gè)參數(shù)相等,按照參數(shù)順序排序
let arr = [1,2,10,20,3]
arr.sort((prev,next) => prev - next) // [1, 2, 3, 10, 20]

以上的方法適用于元素的 valueOf 方法返回?cái)?shù)值(或者可以隱式轉(zhuǎn)換為數(shù)值)的情況,因?yàn)橹挥袛?shù)值才可以做減法的。如果元素的 valueOf 方法返回的不是數(shù)值(或者可以隱式轉(zhuǎn)換為數(shù)值),就需要我們手動(dòng)進(jìn)行判斷,然后進(jìn)行返回:

let arr = [{val:1},{val:2},{val:10},{val:20},{val:3}]
arr.sort((prev,next) => {
    return prev.val - next.val
}) //  [{val:1},{val:2},{val:3},{val:10},{val:20}]

注意:reversesort 方法都會(huì)在原始的數(shù)組上進(jìn)行修改。

操作方法

1.concat 方法
該方法用來(lái)進(jìn)行數(shù)組合并,接受的參數(shù)如下:

  • 無(wú)參數(shù):返回一個(gè)當(dāng)前數(shù)組的副本
  • 參數(shù)為一個(gè)或多個(gè)變量、數(shù)組:合并當(dāng)前數(shù)組和參數(shù)元素,返回合并后的數(shù)組

如果參數(shù)中含有數(shù)組,則會(huì)將該數(shù)組拆開(kāi),并合并到新數(shù)組中。

[].concat(1,2,[3,[4,5]]) //[1,2,3,[4,5]]

該方法不會(huì)對(duì)原始數(shù)組進(jìn)行修改。
2.slice 方法
該方法用來(lái)從原始數(shù)組中截取一部分元素,基于這些元素再創(chuàng)建一個(gè)新數(shù)組。
slice 方法的參數(shù):

  • 起始位置:截取數(shù)組時(shí)的起始位置,可為負(fù)數(shù),可選,默認(rèn)為0
  • 結(jié)束位置:截取數(shù)組時(shí)的結(jié)束位置,可為負(fù)數(shù),可選,默認(rèn)為數(shù)組的長(zhǎng)度

當(dāng) slice 的參數(shù)為負(fù)數(shù)時(shí),該參數(shù)和數(shù)組長(zhǎng)度的和就是實(shí)際截取時(shí)的啟示/結(jié)束位置,如果結(jié)束位置(經(jīng)計(jì)算轉(zhuǎn)化后)小于起始位置(經(jīng)計(jì)算轉(zhuǎn)化后),則返回一個(gè)空數(shù)組。

[1,2,3].slice() //[1,2,3]
[1,2,3].slice(1) //[2,3]
[1,2,3].slice(-2,-1) //[2]
[1,2,3].slice(-1,-2) //[]
...

slice 方法不會(huì)修改原始數(shù)組。
3.splice 方法
該方法較強(qiáng)大,可以用來(lái)刪除、插入、替換數(shù)組元素。該方法會(huì)對(duì)原始數(shù)組進(jìn)行修改。
1)刪除元素
使用 splice 方法刪除數(shù)組元素需要兩個(gè)參數(shù):

  • 刪除元素的起始位置
  • 刪除元素的個(gè)數(shù)

返回被刪除的元素組成的數(shù)組。

let arr = [1,2,3]
arr.splice(0,1) //[1]
arr //[2,3]

2)插入元素
使用 splice 方法插入元素需要至少三個(gè)參數(shù):

  • 插入的起始位置
  • 0 (表示不刪除元素)
  • 插入的元素序列,可為多個(gè)

由于沒(méi)有刪除元素,因此調(diào)用該方法返回一個(gè)空數(shù)組

let arr = [1,2,3]
arr.splice(0,0,"memeda","heheda") //[]
arr // ["memeda", "heheda", 1, 2, 3]

3)替換元素
使用 splice 方法替換元素的原理是先刪除該元素,在在其位置上進(jìn)行替換,在替換時(shí)可以使用多個(gè)元素序列。

let arr = [1,2,3]
arr.splice(1,1,"memeda","heheda") //[2]
arr //[1, "memeda", "heheda", 3]

位置方法

數(shù)組中有兩個(gè)位置方法:indexOflastIndexOf,這兩個(gè)方法用來(lái)查找元素在數(shù)組中的位置。indexOf 是從數(shù)組開(kāi)頭開(kāi)始尋找,找到第一個(gè)匹配的元素便停止,如果沒(méi)有匹配到元素,則返回 -1,lastIndexOf 從數(shù)組的結(jié)尾開(kāi)始尋找,匹配方式類似。
需要注意的是,indexOflastIndexOf 匹配元素時(shí)要求嚴(yán)格相等(===)。
另外,這兩個(gè)方法還可以接受起始位置和結(jié)束位置兩個(gè)參數(shù)(可選),表示搜尋的位置。

let person = {name:"MIKE"}
let arr1 = [{name:"MIKE"}]
let arr2 = [person]
arr1.indexOf(person) //-1
arr2.indexOf(person) //0

由于使用 indexOflastIndexOf 方法匹配元素時(shí)要求嚴(yán)格相等,因此 arr1 數(shù)組并不能匹配到 person 對(duì)象。

迭代方法

數(shù)組還有幾個(gè)迭代方法,用來(lái)對(duì)數(shù)組內(nèi)部的元素做一些迭代操作,這些方法都接受一個(gè)函數(shù)作為參數(shù),每次進(jìn)行迭代時(shí)都會(huì)執(zhí)行該函數(shù)。該函數(shù)的參數(shù)為:值、位置、原數(shù)組
1.every 方法
該方法用來(lái)對(duì)數(shù)組的每一項(xiàng)進(jìn)行迭代,如果函數(shù)對(duì)每一個(gè)元素都返回 true,則 every 的返回結(jié)果為 true

[1,2,3].every((v)=> v>0) //true
[1,2,3].every((v)=> v>1) //false

2.some 方法
該方法和 every 方法類似,但不要求函數(shù)對(duì)每一個(gè)元素返回 true,只要有一個(gè)元素在迭代時(shí)返回 truesome 方法就返回 true
true,則 every 的返回結(jié)果為 true

[1,2,3].some((v)=> v>0) //true
[1,2,3].some((v)=> v>1) //true

3.filter 方法
該方法用來(lái)對(duì)數(shù)組的每一項(xiàng)進(jìn)行過(guò)濾,返回符合要求的元素列表.

[1,2,3].filter(v=>v%2) //[1,2]

4.forEach 方法
該方法用來(lái)對(duì)數(shù)組的每一項(xiàng)進(jìn)行操作,該方法沒(méi)有返回值,也不會(huì)影響原始數(shù)組,類似于普通的 for 循環(huán)。

[1,2,3].forEach(v=>{ console.log(v) }) // 1,2,3

5.map 方法
該方法用來(lái)對(duì)數(shù)組的每一項(xiàng)進(jìn)行操作,然后將操作的結(jié)果映射到一個(gè)新數(shù)組。

[1,2,3].map(v=>v*2) //[2,4,6]

歸并方法

數(shù)組還有兩個(gè)歸并方法:reducereduceRight
這兩個(gè)方法會(huì)對(duì)數(shù)組的每一項(xiàng)進(jìn)行迭代,然后構(gòu)建一個(gè)最終的返回值。可以接受四個(gè)參數(shù):

  • 前一個(gè)值
  • 后一個(gè)值
  • 當(dāng)前索引
  • 原數(shù)組對(duì)象

在迭代的過(guò)程中,函數(shù)的返回值會(huì)作為第一個(gè)參數(shù)傳入下一次的迭代的函數(shù)中,并最終返回一個(gè)最終值。在第一次進(jìn)行迭代時(shí),前一個(gè)參數(shù)和后一個(gè)參數(shù)分別是數(shù)組的第一個(gè)元素和第二個(gè)元素。
reduceRight 從數(shù)組的末尾開(kāi)始?xì)w并,其他和 reduce 一致。

// 對(duì)數(shù)組的每一項(xiàng)相乘
[1,2,3,4,5].reduce((prev,next) => prev * next) //120
[1,2,3,4,5].reduceRight((prev,next) => prev + next) //15

當(dāng)涉及到對(duì)數(shù)組元素的累加、累積等操作時(shí),這兩個(gè)方法很好用。

完。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 第5章 引用類型(返回首頁(yè)) 本章內(nèi)容 使用對(duì)象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學(xué)一百閱讀 3,268評(píng)論 0 4
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,533評(píng)論 1 51
  • 我以為我已經(jīng)不再渴望收到禮物 可是當(dāng)它出現(xiàn)在我眼前 我的心瞬間充盈 仿佛回到初戀 心儀的禮物 一定是懂你的人才會(huì)送...
    攝影師靜心閱讀 397評(píng)論 1 1