前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ES6入门之数组的扩展

ES6入门之数组的扩展

作者头像
执行上下文
发布2022-07-26 14:10:06
1960
发布2022-07-26 14:10:06
举报
文章被收录于专栏:执行上下文

1. 扩展运算符

...表示,将一个数组转为用逗号分隔的参数序列,如下:

代码语言:javascript
复制
console.log(...[1,2,3]) // 1 2 3

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

[...document.querySelectorAll('div')] // [<div>, <div>, <div>]


function add(x, y){
    return x + y
}
const n = [3, 5]
add(...n) // 8
扩展运算符可以和正常函数结合使用,如下:
代码语言:javascript
复制
function f(a,b,c,d,e){
    console.log(a,b,c,d,e)
}
const age = [0,1]

f(-1,...age,2,...[3]) // -1 0 1 2 3
扩展运算符后面也可以是表达式,如下:
代码语言:javascript
复制
const x = 10
const arr = [
    ...(x > 0 ? ['a'] : []), 'b',
]

arr // ['a', 'b']
重要:如果扩展运算符后面是一个空数组,将不会有任何效果。另外只有在函数调用的时候扩展函数在放在圆括号之内,其他的则会报错。
替代函数的apply方法

扩展函数可以展开数组,所以将不需要apply方法来将数组转换为函数的参数。

代码语言:javascript
复制
function f(x, y, z){
    console.log(x, y, z)
}

var a = [1,2,4]

// ES5 
f.apply(null, args)

// ES6
f(...a)


// Math.max方法

//ES5
Math.max.apply(null, [14, 3, 99])

//ES6
Math.max(...[12, 4, 55])

//等同于
Math.max(12, 4, 55)

// push方法的应用

var a = [0,1,2]
var b = [3,4,5]

//ES5
Array.prototype.push.apply(a,b) // 0,1,2,3,4,5

//ES6
a.push(...b)
扩展运算符的应用
1. 复制数组
代码语言:javascript
复制
因为数组是复合的数据类型,直接的复制只是复制数组在堆内存中的指针地址

    const a1 = [1,2]
    const a2 = a1

    a2[0] = 3
    a1 // [3,2]

    // ES5 通过变通方法来复制
    const a1 = [1,2]
    const a2 = a1.concat()

    a2[0] = 23
    a1 // [1,2]

    // ES6写法
    const b1 = [1,3]
    const b2 = [...b1] or [...b2] = b1
2. 合并数组
代码语言:javascript
复制
const a1 = ['b', 'c']
    const a2 = ['d']
    const a3 = ['x', 'y']

    // ES5中合并数组
    a1.concat(a2, a3)

    // ES6中合并数组
    [...a1, ...a2, ...a3]

    //以上两种都是浅拷贝,修改原数组和同步新数组
3. 与解构赋值一起使用,扩展只能放在最后一位,不然会报错
代码语言:javascript
复制
// ES5
    a = list[0], rest = list.slice(1)

    // ES6
    [a,...rest] = list

    // 其他
    const [a,...c] = [1,2,4,5,4,6] // a 1   c 2,4,5,4,6
    const [a,...c] = [] // a undefined   c []
    const [a,...c] = ['a'] // a 'a'   c []
4. 字符串,将字符串转换为数组
代码语言:javascript
复制
[...'hello'] // [h,e,l,l,0]
5. 实现了Iterator接口的对象
代码语言:javascript
复制
任何定义了遍历器接口对象,都可以用扩展运算符转为真正的数组

    let nodelist = document.querySelectorAll('div')
    let array = [...nodelist]
    // querySelectorAll 返回的是一个类数组,通过扩展运算符
    将其转换为一个真正的数组
6. Map 和 Set 解构,Generator函数
代码语言:javascript
复制
扩展运算符调用的是数据解构的Iterator接口,只要有Iterator接口的
    对象,都可以使用扩展运算符

    // Map
    let map = new Map([
        [1, 'a'],
        [2, 'b'],
        [3, 'c'],
    ])
    let arr = [...map.keys()] // 1, 2, 3
    let arr = [...map.values()] // 'a', 'b', 'c'

    //Generator函数
    const go = function*(){
        yield 1;
        yield 2;
        yield 3;
    }
    [...go()] // [1, 2, 3]

2. Array.from()

Array.from 方法用于将两类对象转为真正的数组。1、类似数组对象 和 可遍历的对象(包裹Set和Map),如下:

代码语言:javascript
复制
let arrLike = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
    length: 3
}

// ES5 
var a1 = [].slice.call(arrLike)

// ES6
var a2 = Array.from(arrLike)

在实际中,像获取dom后返回的Nodelist集合,以及函数内部的arguments对象就是类数组,通过 Array.from将它们转换为真正的数组。

代码语言:javascript
复制
// NodeList 对象
let ps = document.querySelectorAll('p')
Array.from(ps).filter(p => {
    return p.textContent.length > 100
})

// arguments 对象
function foo(){
    var arg = Array.from(arguments)
}

// 只要部署了Iterator接口的数据解构,Array.from都能将其转成数组
Array.from('hello') // ['h', 'e', 'l', 'l', 'o']

let nl = new Set([1, 2])
Array.from(nl) // [1, 2]

// 如果是真数组则返回一样的
Array.from([1, 2, 3]) // [1, 2, 3]

... 扩展运算符也可以将某些类数组转换为数组,如arguments和NodeList集合 拥有lenght属性的对象都可以通过Array.from转换为数组,而扩展运算符则不行。

代码语言:javascript
复制
Array.from({lenght:3}) // [undefined, undefined, undefined]

对于低版本的浏览器,可以通过 Array.prototype.slice 方法替代

Array.from 还可以接受第二个参数如同map一样,用来对每个元素进行操作,并将处理后的值放入返回的数组中。

代码语言:javascript
复制
const arrlike = new Set([1,2,3])
Array.from(arrlike, x => x * x)   // =
Array.from(arrlike).map(x => x * x)   // [1, 4, 9]

//注意: 如果map中用到了this,可以传入Array.from
的第三个参数,用来绑定this

Array.from 可以将各种值转换为真正的数组,并且还提供map相关功能,这样代表如果有个原始数据结构,可以先将他转换为数组,然后使用数组相关的方法。

3. Array.of()

用于将一组值,转换为数组。主要用来弥补Array函数因为参数个数不同而导致的差异

代码语言:javascript
复制
Array.of(3,11,6) // [3, 11, 6]
Array.of(3) // [3]
Array.of(4).length // 1

4. 数组的实例 copyWithin()

将当前数组中指定位置的元素复制到另外一个位置,并且会覆盖那个位置的原有元素,会修改当前数组

代码语言:javascript
复制
// 有三个参数
1. target(必须):从该位置开始替换数据,如果是负值,则倒数
2. start(可选):从该位置读取数据,默认0,负值同上
3. end(可选):到这个位置停止读取数据,默认等于数组长度,负值同上


let p = [1,2,3,4,5,6,7]
p.copyWithin(0,5,7)
[6, 7, 3, 4, 5, 6, 7]

5. 数组实例的 find() 和 findIndex()

find 用来找出数组中符合条件的成员,它的参数是一个回调函数,找到一个返回值为true的返回,如果没有则返回undefined

代码语言:javascript
复制
let s = [1,2,3,4,5,6]

s.find(x => x > 4)
// 5

find 方法的回调函数有三个参数

    value // 当前值
    index // 当前的位置
    arr // 原数组

findIndex 同find方法类似,只不过都不符合返回的是 -1,而且符合是返回符合条件值的位置而不是值。

代码语言:javascript
复制
let s = [1,2,3,4,5,6]

s.find(x => x > 4)
// 4

find 和 findIndex 都可以接受第二个参数

代码语言:javascript
复制
function o(p){
    return p > this.age
}

const u = {name: 'cx', age: 11}
const y = [8,11,22,2,4]

y.find(o, u) // 22  返回的值
y.findIndex(o, u) // 2  返回值的位置

6. 数组实例的 fill()

通过给定值,填充一个数组

代码语言:javascript
复制
let sz = [1,2,3,4,5,6]

sz.fill(1) // [1,1,1,1,1,1]

sz.fill(1,0,3) 
// 接受三个参数,第一个为填充值,第二个为起始位置,第三个为截至位置

sz.fill(1,3)
// 如果省略最后一个参数,则默认从起始位置到数组默认长度结束

7. 数组实例的 entries(), keys(), values()

三种方法主要用于遍历数组,可以用 for...of...进行遍历,keys()对应键名,values对应键值,entries()对键值对的遍历

代码语言:javascript
复制
let bo = ['a', 'c']

for(let r of bo.keys()){
    console.log(r) // 0 1
}
// 0 1

for(let n of bo.values()){
    console.log(n) 
}
// a c

for(let s of bo.entries()){
    console.log(s)
}
// [0, "a"]
// [1, "c"]

8. 数组实例的 includes()

用来表示某个数组是否包含给定的值,返回一个布尔值

代码语言:javascript
复制
let i = ['a',1,2,3]

i.includes()  // false
i.includes(1) // true
i.includes(10) // false

indexOf 和includes 的区别

代码语言:javascript
复制
indexOf // 不够语义化,它的作用是找到参数出现的第一个位置,
所以要比较是否为 -1,另外由于 内部使用的是 ===  则导致NaN
的误判。

// [NaN].indexOf(NaN) // -1

includes // 使用的是不一样的算法,则不会有这个问题

// [NaN].includes(NaN) // true

Map 和 Set 的has 方法和includes的区别

代码语言:javascript
复制
Map 的has 方法是用来查找键名的
Set 的has 方法是用来查找值的

9. 数组的实例 flat(), flatMap()

flat() 将嵌套的二维数组变成一维数组,如果需要拉平多维数组,则flat(多维数量) 或者使用 Infinity 直接转为一维数组

代码语言:javascript
复制
let rw = [1,2,3,[4,5,6],7]
rw.flat()  // [1, 2, 3, 4, 5, 6, 7]

let dw =  [1,2,3,[4,5,6,[7,8],[2,['a','b'],4,5]],[5,6,]]
dw.flat(3) // [1, 2, 3, 4, 5, 6, 7, 8, 2, "a", "b", 4, 5, 5, 6]

// 如果你不知道是多少层嵌套而都想转成一维,可以使用 Infinity
dw.flat(Infinity) 
// [1, 2, 3, 4, 5, 6, 7, 8, 2, "a", "b", 4, 5, 5, 6]

flatMap() 对数组执行map,然后对返回值组成的数组 执行flat,不会改变原数组。flatMap只能展开一层数组。

代码语言:javascript
复制
let mp = [2,3,4,5]

mp.flatMap((item) => [item, item* 2])
// [2, 4, 3, 6, 4, 8, 5, 10]
====
mp.map((item) => [item, item*2])
// [[2,4],[3,6],[4,8],[5,10]]
mp.flat()
// [2, 4, 3, 6, 4, 8, 5, 10]

10. 数组的空位(避免出现空位)

数组的空位指的是该数组中某一个位置没有任何值。另外空位不是undefined,如果一个位置的值是undefined,那么这个位置还是有值的。

代码语言:javascript
复制
Array(3) // [, , ,]

ES5中大多数情况中对待空位都是会忽略

代码语言:javascript
复制
- forEach(), filter(), reduce(), every() 和 some() 都会跳过空位
- map() 跳过但保留这个值
- join() 和 toString() 中 空位 === undefined,而 undefined和null会被处理成空字符串

ES6 中 空位则转换为undefined

代码语言:javascript
复制
- Array.from([1,,2]) // [1, undefined, 2]
- [...['a',,'b']]    // [ "a", undefined, "b" ]

entries()
keys()
values()
find()
findIndex()  // 都会将空位处理成undefined。

ES6入门系列

ES6入门之let、cont

ES6入门之解构赋值

ES6入门之字符串的扩展

ES6入门之正则的扩展

ES6入门之数值的扩展

ES6入门之函数的扩展

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-05-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 执行上下文 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 扩展运算符
    • 扩展运算符可以和正常函数结合使用,如下:
      • 扩展运算符后面也可以是表达式,如下:
        • 替代函数的apply方法
          • 扩展运算符的应用
          • 2. Array.from()
          • 3. Array.of()
          • 4. 数组的实例 copyWithin()
          • 5. 数组实例的 find() 和 findIndex()
          • 6. 数组实例的 fill()
          • 7. 数组实例的 entries(), keys(), values()
          • 8. 数组实例的 includes()
          • 9. 数组的实例 flat(), flatMap()
          • 10. 数组的空位(避免出现空位)
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档