ES6(三)—— 數組

目錄

  • 數據的重要功能【遍歷、轉換、生成、查找】
  • 數組遍歷node

    • ES5中遍歷有多少種方法?es6

      • for循環
      • forEach
      • every
      • for-in
    • ES6新增for-of數組

      • 爲何es6要新增一個for-of?
      • for-of不能直接遍歷對象? —— 關於可迭代接口
    • 優點和缺點
  • 將僞數組轉換成數組數據結構

    • 什麼是僞數組?
    • ES5的轉換
    • ES6的轉換
  • 建立新數組函數

    • ES5
    • ES6學習

      • Array.from
      • Array.of
      • Array.prototype.fill
  • 數組中查找元素this

    • ES5
    • ES6spa

      • Array.prototype.find
      • Array.prototype.findIndex
  • 函數參數prototype

    • Array.from(arrayLike,mapFn,thisArg)
    • Array.of(element0[,element1...])
    • Array.fill(value,start,end)
    • Array.find(callback[, thisArg])
    • Array.findIndex(callback[, thisArg])
  • ES6-ES10學習版圖

數據的重要功能【遍歷、轉換、生成、查找】

數組遍歷

ES5中遍歷有多少種方法?

const arr = [1,2,3,4,5]
for循環
for (let i = 0;i < arr.length; i++) {
    console.log(arr[i]) // 1 2 3 4 5
}
forEach

數組遍歷方法3d

arr.forEach(function(item){
    console.log(item) //1 2 3 4 5
})

代碼簡潔上看,forEachfor循環寫法要簡潔。

可是forEach不支持reakcontinue,每一個元素必須遍歷到

// for循環能夠使用break控制遍歷中止
for (let i = 0;i < arr.length; i++) {
    if(arr[i] === 2){
        break
    }
    console.log(arr[i]) // 1
}

// for循環能夠使用continue控制遍歷跳過
for (let i = 0;i < arr.length; i++) {
    if(arr[i] === 2){
        continue
    }
    console.log(arr[i]) // 1 3 4 5
}

//forEach不支持break和continue
arr.forEach(function(item){
    if(item === 2) {
        break // or continue 都會報錯 Unsyntactic break 語法不支持
    }
    console.log(item)
})

arr.forEach(function(item){
    if(item === 2) {
        return false //跳過本此循環 相似continue
    }
    console.log(item) // 1 3 4 5
})
every

數組遍歷方法

arr.every(function(item){
    console.log(item) // 1
})
// every繼不繼續遍歷取決於返回值,爲true則繼續遍歷,false退出。默認是false
// 若是要所有遍歷完成 須要返回true
arr.every(function(item){
    console.log(item)  // 1 2 3 4 5
    return true
})

// 能夠經過返回的true or false 來控制循環
arr.every(function(item){
    if(item === 2) {
        return false //至關於for循環中的break
    }
    console.log(item)  // 1
    return true
})
for-in

for-in自己是未object遍歷的,而不是爲數組。雖然能夠遍歷數組,可是有瑕疵。

for-in中能夠使用continuebreak,可是不支持寫return,會報錯Illegal return statement

// 之因此數組能夠用for-in取遍歷
// 是由於1.數組是對象的一種 2.數組是可遍歷的
for (let index in arr) {
    console.log(index, arr[index])
}
// 0 1
// 1 2
// 2 3
// 3 4
// 4 5


//瑕疵一:
// 由於arr是一個對象,因此能夠定義屬性並賦值
arr.a = 8
for (let index in arr) {
    console.log(index, arr[index])
}
// 再次進行遍歷
// 0 1
// 1 2
// 2 3
// 3 4
// 4 5
// a 8  這個時候a不是索引,而是字符串,若是這裏咱們仍是覺得遍歷以後只是返回索引就容易出現bug


//瑕疵二:
for(let index in arr) {
    if(index === 2) {
        continue
    }
    console.log(index, arr[index])
}
// 0 1
// 1 2
// 2 3
// 3 4
// 4 5
//爲何能夠使用continue可是continue卻沒有起做用
//由於這個時候index是字符串而不是索引

//解決方法一:只判斷值,不判斷類型
for(let index in arr) {
    if(index == 2) {
        continue
    }
    console.log(index, arr[index])
}
// 0 1
// 1 2
// 3 4
// 4 5
//解決方法二:將index隱式轉化成數字類型
for(let index in arr) {
    if(index * 1 === 2) {
        continue
    }
    console.log(index, arr[index])
}
// 0 1
// 1 2
// 3 4
// 4 5

for-of(ES6新增)

// item不是下標,直接是值,且能夠使用break終止循環
for(let item of arr) {
    console.log(item) // 1 2 3 4 5
}
爲何es6要新增一個for-of?
要判斷一個對象是否是可遍歷的,不能說其是否是一個數組 or Object。

ES6容許用戶自定義數據結構,這種數據結構既不是數組,也不是Object,可是都是可遍歷的。這種數據結構進行遍歷,不能用數組的也不能用for-in,就須要新增一種for-of去遍歷

舉例子:

// 定義一個數據結構,想要遍歷拿到類別中的最低值
const Price = {
    A: [1.5, 2.3, 4.5],
    B: [3, 4, 5],
    C: [0.5, 0.8, 1.2]
}

for (let key in Price) {
    console.log(key, Price[key])
    // [1.5, 2.3, 4.5]
    // [3, 4, 5]
    // [0.5, 0.8, 1.2]
}
// 使用for-in只能返回數組,沒法直接把三個最低值遍歷出來
for-of不能直接遍歷對象? —— 關於可迭代接口

for-of能夠用來遍歷Set結構和Map結構,可是不能夠直接遍歷object,由於其不是可遍歷的對象,Iterable接口沒有實現。

下面看一下:數組、Set和Map的原型對象上有迭代器

數組.png

Set對象.png

Map對象.png
Object.png
對象方法上面沒有

Object.png

那麼咱們調用一下數組上面的iterator方法

const arr = ['foo', 'bar', 'baz']
console.log(arr[Symbol.iterator]())
// 返回一個iterator的對象,其原型對象上面有next方法
// Array Iterator {}  
//  __proto__: Array Iterator
//    next: ƒ next()   
//    Symbol(Symbol.toStringTag): "Array Iterator"
//    __proto__: Object
const iterator = arr[Symbol.iterator]()

console.log(iterator.next()) // { value: 'foo', done: false }
console.log(iterator.next()) // { value: 'bar', done: false }
console.log(iterator.next()) // { value: 'baz', done: false }
console.log(iterator.next()) // { value: undefined, done: true }

能夠看到for-of內部的循環規則,裏面有一個迭代器。只要對象能夠實現Iterable接口就能夠使用for-of進行循環。下面對一個對象進行可迭代改造。

優點和缺點

循環方式 優點 缺點 特色
for循環 支持break和continue 不支持return
forEach 寫法比for簡潔明瞭 所有遍歷,不支持break和continue return false至關於continue
every 能夠支持相似for的break和continue
for-in 能夠遍歷object 遍歷數組的時候存在瑕疵 不支持return
for-of(ES6新增) 能夠遍歷除數組和object以外可遍歷的數據結構,支持break和continue 不支持return
  • return只能用在函數體內,出如今代碼的任何地方都會報錯

將僞數組轉換成數組

什麼是僞數組?

簡單理解:
具有一些數組的特性:可遍歷、有長度。可是不能直接調用數組的API,相似於 argumentsDOM nodeList

嚴格理解:

  1. 按照索引方式存儲數據
  2. 具有length屬性
{0:'2',1:'b',length:2} 這種類型均可以稱之爲僞數組

爲何要將僞數組轉換成數組?

若是想要使用數組的API,就須要將僞數組轉換爲數組

ES5的轉換

let args = [].slice.call(arguments) //collection
// arguments 只能在函數體內使用
// ES6已經廢棄arguments的使用
let imgs = [].slice.call(document.querySelectorAll('img')) // NodeList

ES6的轉換

Array.from

let args = Array.from(arguments)
let imgs = Array.from(document.querySelectorAll('img'))

大體說一下Array.from這個函數

Array.from(arrayLike,mapFn,thisArg)<br/>
第一個參數:僞數組,必須<br/>
第二個參數:遍歷函數,非必須<br/>
第三個函數:this對象,非必須

舉一個例子:
初始化一個長度爲5的數組

//ES5 
let array = Array(5)

array.forEach(function (item) {
    item = 1
})
console.log(array) // [empty × 5] forEach只會遍歷存在的元素

//使用for循環能夠遍歷,可是依舊是先聲明,後賦值
for (let i = 0, len = array.length; i < len; i++) {
    array[i] = 1
}
console.log(array) // [1,1,1,1,1]

// 先將數組轉化爲5個空字符串數組,而後每一個遍歷賦值
let arr = Array(6).join(' ').split('').map(item => 1)
console.log(array) // [1,1,1,1,1]

// ES6
//使用Array.from能夠達到初始化並填充的效果
let array = Array.from({ length: 5 }, function () { return 1 })
console.log(array) // [1,1,1,1,1]
// 上面之因此第一個參數能夠傳{ length: 5 },是由於第一個參數應該傳僞數組

//使用Array.fill能夠快速實現初始化並填充
let array = Array(5).fill(1)
console.log(array) //[1,1,1,1,1]

建立新數組

ES5

let array = Array(5)
let array = ['', ''] //沒法定義長度,只能每一個都初始化爲空字符串

ES6

Array.from
let array = Array.from({ length: 5 })
Array.of
let array = Array.of(1,2,3,4,5) //參數是依此放進去的元素,能夠一個參數能夠多個
console.log(array) //[1,2,3,4,5]
Array.prototype.fill
let array = Array(5).fill(1) //參數是依此放進去的元素,能夠一個參數能夠多個
console.log(array) //[1,1,1,1,1]
Array.fill(value,start,end)<br/>
第一個參數:填充值<br/>
第二個參數:起始位置,默認爲數組的開始<br/>
第三個函數:結束位置,默認爲數組的結束<br/>
[start,end)
let array = [1, 2, 3, 4, 5]
console.log(array.fill(8, 2, 4)) // [1,2,8,8,5]

數組中查找元素

ES5

查找元素包括看元素在不在數組中,也包括根據某個條件去篩選。

// 一
let array = [1, 2, 3, 4, 5]
let find = array.filter(function (item) {
    return item === 3
})
console.log(find) // [3]
// 能找到沒找到都返回一個數組,根據數組的長度判斷數組中有或者沒有元素

let find = array.filter(function (item) {
    return item % 2 === 0
})
console.log(find) // [2,4]
// 若是數組中數據特別大,只是要有仍是沒有,並不要全部的數據

// 二
// 使用every也能夠進行判斷可是咱們須要額外定義變量
let isExt
array.every(function (item) {
    if (item === 3) {
        isExt = item
        return false
    }
    return true
})
console.log(isExt) // 3

ES6

Array.prototype.find

找到查找元素返回其值,找不到返回undefined

let array = [1, 2, 3, 4, 5]
let find = array.find(function(item){
    return item === 3
})
console.log(find)  // 2---當前值

let find1 = array.find(function(item){
    return item === 6
})
console.log(find1)  // undefined---沒有找到

let find2 = array.find(function(item){
    return item % 2 === 0
})
console.log(find2)  // 2---找到2就再也不繼續找了
Array.prototype.findIndex

找到查找元素返回其索引位置,找不到返回-1

let find = array.findIndex(function(item){
    return item % 2 === 0
})
console.log(find)  // 1---索引位置

函數參數

Array.from(arrayLike,mapFn,thisArg)

第一個參數:僞數組,必須<br/>
第二個參數:遍歷函數,非必須<br/>
第三個函數:this對象,非必須

Array.of(element0[,element1...])

參數:任意個參數,依此成爲數組的元素

Array.fill(value,start,end)

第一個參數:填充值<br/>
第二個參數:起始位置,默認爲0<br/>
第三個函數:結束位置,默認爲this.length<br/>
[start,end)

Array.find(callback[, thisArg])

第一個參數:回調函數,接收三個參數,element、index、array<br/>
第二個參數:this對象

Array.findIndex(callback[, thisArg])

第一個參數:回調函數,接收三個參數,element、index、array<br/>
第二個參數:this對象

學習版圖

相關文章
相關標籤/搜索