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

栏目: JavaScript · 发布时间: 5年前

内容简介:讲讲ES6的一些数组的新方法吧,之前面试有问到,自己用了一下还挺好用,先看看数组新方法的列表扩展运算符concat方法最终会返回一个拼接完的数组,也就是我们所需的结果

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

  • 扩展运算符
  • Array.from()
  • Array.of()
  • copyWithin()
  • find() findIndex()
  • fill()
  • entries() keys() values()
  • includes()
  • flat() flatMap()

扩展运算符

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

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','dddd']]
    console.log(arr2) //[1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 1, 2, 3, 4, "aaaa", "bbbb", "dddd"]

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

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()方法

改方法可接收三个参数:

(使用的不多,继续抄文档)

  • 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(原数组,选填)

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


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

JavaScript权威指南(第6版)

JavaScript权威指南(第6版)

David Flanagan / 淘宝前端团队 / 机械工业出版社 / 2012-4-1 / 139.00元

本书是程序员学习核心JavaScript语言和由Web浏览器定义的JavaScript API的指南和综合参考手册。 第6版涵盖HTML 5和ECMAScript 5。很多章节完全重写,以便与时俱进,紧跟当今的最佳Web开发实践。本书新增章节描述了jQuery和服务器端JavaScript。 本书适合那些希望学习Web编程语言的初、中级程序员和希望精通JavaScript的JavaSc......一起来看看 《JavaScript权威指南(第6版)》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

在线进制转换器
在线进制转换器

各进制数互转换器

MD5 加密
MD5 加密

MD5 加密工具