资讯专栏INFORMATION COLUMN

ES6数组方法使用心得以及一些数组操作整理

hosition / 2604人阅读

摘要:讲讲的一些数组的新方法吧,之前面试有问到,自己用了一下还挺好用,先看看数组新方法的列表扩展运算符扩展运算符在中我们要将两个打散数组合并会用到数组对象的方法方法最终会返回一个拼接完的数组,也就是我们所需的结果如果用扩展运算符又是如何操作呢不仅

讲讲ES6的一些数组的新方法吧,之前面试有问到,自己用了一下还挺好用,先看看数组新方法的列表

扩展运算符

Array.from()

Array.of()

copyWithin()

find() findIndex()

fill()

entries() keys() values()

includes()

flat() flatMap()

扩展运算符
在ES5中我们要将两个打散数组合并会用到数组对象的concat方法
let arr = [1,2,3,4,5,6,7,8,9,0]
    console.log(arr.concat([1],[1,2,3,4],"aaaa",["bbbb","ffffdd"])) //[1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 1, 2, 3, 4, "aaaa", "bbbb", "ffffdd"]

concat方法最终会返回一个拼接完的数组,也就是我们所需的结果
如果用扩展运算符又是如何操作呢?

let arr = [1,2,3,4,5,6,7,8,9,0]
    console.log(...arr)  //1 2 3 4 5 6 7 8 9 0
    let arr2 = [...arr,...[1],...[1,2,3,4],"aaaa",...["bbbb","ffffdd"]]
    console.log(arr2) //[1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 1, 2, 3, 4, "aaaa", "bbbb", "ffffdd"]

不仅可以打散数组,扩展运算符也可以打散字符串

console.log([..."hello world"]) //["h","e","l","l","o"," ","w","o","r","l","d"]

当然也能运用于数组的解构赋值

 let [a,...b] = [1,2,3,4,5,6]
    console.log(a)//1
    console.log(b)//[2,3,4,5,6]
    //但是必须要知道的一点是在进行数组的解构赋值时只能作用于数组的最后一位,不然会报错!
    let[...c,d] = [22,33,44,55] //Uncaught SyntaxError: Rest element must be last element

当然也可以和Aray.from()一样,将一个类数组转换成数组

let set = new Set([1,2,3,4,5,6,7,8])
    console.log([...set]) //[1, 2, 3, 4, 5, 6, 7, 8]

运行后可知,...可将Array对象打散,在数组中打散则会返回一个新的数组,对于使用长逻辑时,有时候concat可能会使代码看起来并不是很易懂,用这个会好很多。但是扩展运算符并不是主要用来打散重组数组的。把它用在方法传参中,会用起来很简洁灵活

let arr = [1,2,3,4,5,6,7,8,9,0]
    function add(...arr){
        let aaa = arguments[0].reduce((i,j)=>{
           return i+j
        })
        console.log(aaa)//45
    }
    add(arr)

当然也可以这样子做

function testFoo(a,b,c,d){
        return a+b+c+d
    }
let arr = [1,2,3,4]
testFoo(...arr)
Array.from()

将类数组对象和迭代器对象转换成数组最常用的应该就是数组去重操作了

let arr = [1,2,3,3,3,3,444,4,4,4,5,5,"a","a","b","f"]
let set = new Set(arr)  //set数据类型中不会存在相同的元素,因此把数组转换成set会将数组中重复的部分去除
let newArr = Array.from(set)  //将set数据类型转换成数组
console.log(newArr) //[1, 2, 3, 444, 4, 5, "a", "b", "f"]

当然它也能像扩展运算符一样,将String字符串转换成数组

let str = "hello world"
let arr = Array.from(str)
console.log(arr)//["h","e","l","l","o"," ","w","o","r","l","d"]

这里要了解一个概念什么是类数组对象一般来说,类数组对象和数组没多大区别在操作上也是

let likeArr = {
        "0":0,
        "1":1,
        "2":"aa",
        "3":"bb",
        "4":"cc",
        "length":5
    }  //是不是和你控制台打印出来的数组对象很像甚至可以这样子做

console.log(likeArr[4])//cc
//我们可以用Array.from()将其转换成真正的数组
let arr = Array.from(likeArr)
console.log(arr)//[0, 1, "aa", "bb", "cc"]

在刚刚操作过程中我第一次在创建类数组对象时忘记定义length属性了,于是控制台报错了,说白了类数组对象都有一个length属性,如果没有则和普通对象没多大区别当然Array.from()也会控制台报错,当然扩展运算符是不能将类数组对象转换成数组的,但是Array.from()可以,对此我们可以用代码进行验证

let likeArr = {
     length:3
}
console.log(Array.from(likeArr))//[undefined,undefined,undefined]
console.log(...likeArr)//Uncaught TypeError: Found non-callable @@iterator

我特地试了一下map数据类型

let map = new Map()
map.set("0","a").set("1","b")
let arr = Array.from(map)
console.log(arr) //[["0","a"],["1","b"]]

发现map数据类型可以被Array.from()转换但是转换成的是一个数组是一个[["键","值"],["键","值"],["键","值"]]数组,一般也不会这么用我私下再去研究

Array.of()

Array.of()的作用是将一组值转换成数组,是不是和concat方法有点像,但是concat方法是作用于数组对象的,而且,如果传入的参数中包含数组是会将数组打散转换成独立值,而Array.of()不同,存入数组,转换成数组后该参数在返回值中还是数组在文档中阮一峰大神是这样子来说明的

这个方法的主要目的,是弥补数组构造函数Array()的不足。因为参数个数的不同,会导致Array()的行为有差异。

举个例子

Array.of(0,1,2,3,4)//[0,1,2,3,4]
Array.of(0)//[0]
//如果我们用传统的生成数组方式会是怎么样?
new Array() //[]
//传入一个参数
new Array(3)//生成一个长度为3的数组 [undefined,undefined,undefined]
//传入多个参
new Array(1,2)//[1,2]

从打印结果可知Array构造方法传入参数数量不同,返回的结果并不统一,而Array.of()却是出奇的统一,这弥补了Array构造方法的不足

在不传入参数时Array.of()会返回一个空数组

Array.of()//[]
数组对象的copyWithin()方法
引用文档中的介绍:数组实例的copyWithin方法,在当前数组内部,将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组。也就是说,使用这个方法,会修改当前数组。

改方法可接收三个参数:
(使用的不多,继续抄文档)

target(必需):从该位置开始替换数据。如果为负值,表示倒数。

start(可选):从该位置开始读取数据,默认为 0。如果为负值,表示倒数。

end(可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示倒数

let arr = [1,2,3,4,5,6,7,8,9]
console.log(arr.copyWithin(0,3,8))//[4, 5, 6, 7, 8, 6, 7, 8, 9]
let arr1 = [1,2,3,4,5,6,7,8,9]
console.log(arr1.copyWithin(0,5))//[6, 7, 8, 9, 5, 6, 7, 8, 9]

文档中有更详细的例子以下抄文档

// 将3号位复制到0号位
[1, 2, 3, 4, 5].copyWithin(0, 3, 4)
// [4, 2, 3, 4, 5]

// -2相当于3号位,-1相当于4号位
[1, 2, 3, 4, 5].copyWithin(0, -2, -1)
// [4, 2, 3, 4, 5]

// 将3号位复制到0号位
[].copyWithin.call({length: 5, 3: 1}, 0, 3)
// {0: 1, 3: 1, length: 5}

// 将2号位到数组结束,复制到0号位
let i32a = new Int32Array([1, 2, 3, 4, 5]);
i32a.copyWithin(0, 2);
// Int32Array [3, 4, 5, 4, 5]

// 对于没有部署 TypedArray 的 copyWithin 方法的平台
// 需要采用下面的写法
[].copyWithin.call(new Int32Array([1, 2, 3, 4, 5]), 0, 3, 4);
// Int32Array [4, 2, 3, 4, 5]
数组对象 find() findIndex()

find()用于找寻数组对象中第一个符合条件的值传入参数是一个回调函数由此可见是一个高阶函数,该方法类似数组对象的every()方法 some()方法 filter()方法,用于鉴别数组中的值,回调方法传入参数也类似都是必传value(值),可选index(索引),与arr(原数组)具体差别用实验来鉴别

let arr = [1,2,3,4,5,6,7,8,9]
//every()方法用于鉴别数组的所有元素是否符合要求并返回boolean
arr.every((value,index,arr)=>{
    return value===7&&index===6
})//false
//some()方法用于鉴别数组中是否有符合要求的值并返回boolean
arr.some((value,index,arr)=>{
   return value===7&&index===6
})//true
//filter()方法将数组中符合要求的值拼接成一个新数组并返回
arr.filter(value=>{
    return value>3
})//[4, 5, 6, 7, 8, 9]
//find()方法返回数组中符合要求的第一个值
arr.find((value)=>{
    return value>3
})//4
//若没有符合要求的值则返回undifined
arr.find((value)=>{
    return value>100
})//undifined

findIndex的用法和find一样,但是返回值不同,find方法是返回符合条件的第一个值,若没有符合要求的值则返回undifined。findIndex则是返回符合条件的第一个值在数组中的位置,若没有符合要求的值则返回-1

arr.findIndex(value=>{
        return value>3
    })//3
arr.findIndex(value=>{
        return value>100
})//-1
数组对象的fill()方法

用于填充数组对象并返回新数组,会改变原数组例子如下

let arr = Array(3)//长度为3的数组 =>[undefined,undefined,undefined]
arr.fill(666)              //[666,666,666]
console.log(arr)           //[666,666,666]
let arr1 = [1,2,3,5,4]
arr1.fill(2333)//[2333, 2333, 2333, 2333, 2333]
迭代器遍历对象entries() keys() values()

自己知道是怎么一回事但是不知道怎么解释,继续引用文档中的解释:ES6 提供三个新的方法——entries(),keys()和values()——用于遍历数组。它们都返回一个遍历器对象,可以用for...of循环进行遍历,唯一的区别是keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历。

    let arr = [1,2,3,4,5,6,7,8,9]
    for (let index of arr.keys()) {
        //返回key值
        console.log(index); //0 1 2 3 4 5 6 7 8
    }
    for (let index of arr.values()){
        //返回value值
        console.log(index); //0 1 2 3 4 5 6 7 8
    }
    for (let index of arr.entries()){
        //返回键值对
        console.log(index) //[0,1],[1,2],[2,3]........
    }

也能配合数组对象的其他高阶函数使用,比如我要创建一个包含过去7天Date的数组

let dateArr = [...Array(7).keys()].map(d=>new Date(Date.now()-d*1000*24*60))
    //[Tue May 28 2019 13:27:00 GMT+0800 (中国标准时间), Tue May 28 2019 13:03:00 GMT+0800 (中国标准时间), Tue May 28 2019 12:39:00 GMT+0800 (中国标准时间), Tue May 28 2019 12:15:00 GMT+0800 (中国标准时间), Tue May 28 2019 11:51:00 GMT+0800 (中国标准时间), Tue May 28 2019 11:27:00 GMT+0800 (中国标准时间), Tue May 28 2019 11:03:00 GMT+0800 (中国标准时间)]

//或者说生成一个0到9的数组
let numArr = [...Array(10).keys()].map(n=>n)
//[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

如果不适用Array.from()或者扩展运算符与高阶函数配合或者不用for of 循环进行配合则需要用到迭代器的next()方法进行往下操作

    let arr = ["a","b","c","d","e"]
    let keysData = arr.keys()
    console.log(keysData.next().value)//0
    console.log(keysData.next().value)//1
    console.log(keysData.next().value)//2

    let valuesData = arr.values()
    console.log(valuesData.next().value)//a
    console.log(valuesData.next().value)//b
    console.log(valuesData.next().value)//c

    let entriesData = arr.entries()
    console.log(entriesData.next().value)//[0,"a"]
    console.log(entriesData.next().value)//[1,"b"]
    console.log(entriesData.next().value)//[2,"c"]

关于ES6迭代器其他操作可自己去理解

数组对象的 includes()方法

非常好用的一个方法,用于判断数组中是否包含某个值若有则返回true,没有则返回false

let arr = [1,2,3,4,5]
arr.includes(2)//true
arr.includes(6)//false

改方法可以传入两个参数,第一个是用于判断是否存在的值,第二个是判断开始位置

let arr = [1,2,3,4,5]
arr.includes(2,3) //false
arr.includes(4,3) //true
数组对象的 flat() flatMap()方法

flat()方法将数组中的数组打散生成一个新的数组,不改变原数组,不好理解是不是?!那还是看例子吧

let arr = [1,2,3,[4,5,6],7,[8,9]]
let newArr = arr.flat() //[1, 2, 3, 4, 5, 6, 7, 8, 9]

但是flat()方法只能打散一层数组,如果数组中嵌套的数组是多维数组则需要传入参数(Number类型),要打散几维数组则传几默认是1

let arr = [1,[2,[3,4,[5,6]]],7]
arr.flat(2) //[1,2,3,4,[5,6],7]
arr.flat(3) //[1,2,3,4,5,6,7]

如果不管数组中有几维数组都要将数组打散成一维数组的话可以传入关键字Infinity

let arr = [1,[2,[3,[4,[5,[6,[7,[8]]]]]]],9]
arr.flat(Infinity)//[1,2,3,4,5,6,7,8,9]

flatMap()方法与flat()类似,都能打散数组,但是flatMap()只能打散一层并且flatMap()与map类似可以传入一个回调函数作为参数,并且返回一个新数组

let arr = [1,[2,[3,[4,[5,[6,[7,[8]]]]]]],9]
    let mapArr = arr.flatMap(i=>{
        return typeof(i)
    })//["number", "object", "number"]

flatMap()方法回调函数参数也与map()方法回调函数参数相同都可以传入value(值,必填),key(索引,选填),arr(原数组,选填)

差不多就这点,主要是我写累了就不写了吧

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/109900.html

相关文章

  • 2017年五月前端面试题目的总结

    摘要:持续心累的找工作阶段算是结束了,不同公司对面试的知识侧重点不同,整体的感受就是大公司可能更偏向一些基础或者原理布局一些经典算法方面。现将我在面试过程遇到的问题总结下。目前先传题目答案整理好之后再发布出来。 持续心累的找工作阶段算是结束了,不同公司对面试的知识侧重点不同,整体的感受就是:大公司可能更偏向一些JS基础或者原理、html布局、一些经典算法方面。小公司的面试更加侧重对经验和细节...

    warkiz 评论0 收藏0
  • 2017年五月前端面试题目的总结

    摘要:持续心累的找工作阶段算是结束了,不同公司对面试的知识侧重点不同,整体的感受就是大公司可能更偏向一些基础或者原理布局一些经典算法方面。现将我在面试过程遇到的问题总结下。目前先传题目答案整理好之后再发布出来。 持续心累的找工作阶段算是结束了,不同公司对面试的知识侧重点不同,整体的感受就是:大公司可能更偏向一些JS基础或者原理、html布局、一些经典算法方面。小公司的面试更加侧重对经验和细节...

    dreamGong 评论0 收藏0
  • 2017年五月前端面试题目的总结

    摘要:持续心累的找工作阶段算是结束了,不同公司对面试的知识侧重点不同,整体的感受就是大公司可能更偏向一些基础或者原理布局一些经典算法方面。现将我在面试过程遇到的问题总结下。目前先传题目答案整理好之后再发布出来。 持续心累的找工作阶段算是结束了,不同公司对面试的知识侧重点不同,整体的感受就是:大公司可能更偏向一些JS基础或者原理、html布局、一些经典算法方面。小公司的面试更加侧重对经验和细节...

    liangzai_cool 评论0 收藏0
  • JavaScript易错知识点整理

    摘要:知识点变量作用域上方的函数作用域中声明并赋值了,且在之上,所以遵循就近原则输出等于。上方的函数作用域中被重新赋值,未被重新声明,且位于之下,所以输出全局作用域中的。若执行则会输出。上方利用方法进行对象的深拷贝可以避免源对象被篡改的可能。 前言 本文是我学习JavaScript过程中收集与整理的一些易错知识点,将分别从变量作用域,类型比较,this指向,函数参数,闭包问题及对象拷贝与赋值...

    2shou 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<