卖坚果的怪叔叔 卖坚果的怪叔叔
  • 首页
  • 生活
  • 技术
  • 记录
  • 工具箱
  • 关于我
首页 › 技术 › ES6入门之数组的扩展

ES6入门之数组的扩展

坚果大叔
2019-05-16 17:25:29技术阅读 2,555

1. 扩展运算符

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

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

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

[...document.querySelectorAll('div')] // [
,
,
] function add(x, y){ return x + y } const n = [3, 5] add(...n) // 8
扩展运算符可以和正常函数结合使用,如下:
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
扩展运算符后面也可以是表达式,如下:
const x = 10
const arr = [
    ...(x > 0 ? ['a'] : []), 'b',
]

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

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

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. 复制数组

    因为数组是复合的数据类型,直接的复制只是复制数组在堆内存中的指针地址
    
    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. 合并数组

    const a1 = ['b', 'c']
    const a2 = ['d']
    const a3 = ['x', 'y']
    
    // ES5中合并数组
    a1.concat(a2, a3)
    
    // ES6中合并数组
    [...a1, ...a2, ...a3]
    
    //以上两种都是浅拷贝,修改原数组和同步新数组
  3. 与解构赋值一起使用,扩展只能放在最后一位,不然会报错

    // 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. 字符串,将字符串转换为数组

    [...'hello'] // [h,e,l,l,0]
  5. 实现了Iterator接口的对象

    任何定义了遍历器接口对象,都可以用扩展运算符转为真正的数组
    
    let nodelist = document.querySelectorAll('div')
    let array = [...nodelist]
    // querySelectorAll 返回的是一个类数组,通过扩展运算符
    将其转换为一个真正的数组
  6. Map 和 Set 解构,Generator函数

    扩展运算符调用的是数据解构的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),如下:

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将它们转换为真正的数组。

// 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转换为数组,而扩展运算符则不行。

Array.from({lenght:3}) // [undefined, undefined, undefined]

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

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

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函数因为参数个数不同而导致的差异

Array.of(3,11,6) // [3, 11, 6]
Array.of(3) // [3]
Array.of(4).length // 1

4. 数组的实例 copyWithin()

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

// 有三个参数
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

let s = [1,2,3,4,5,6]

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

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

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

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

let s = [1,2,3,4,5,6]

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

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

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

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

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()对键值对的遍历

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

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

let i = ['a',1,2,3]

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

indexOf 和includes 的区别

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

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

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

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

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

Map 的has 方法是用来查找键名的
Set 的has 方法是用来查找值的

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

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

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只能展开一层数组。

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,那么这个位置还是有值的。

Array(3) // [, , ,]

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

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

ES6 中 空位则转换为undefined

- Array.from([1,,2]) // [1, undefined, 2]
- [...['a',,'b']]    // [ "a", undefined, "b" ]

entries()
keys()
values()
find()
findIndex()  // 都会将空位处理成undefined。
数组
赞赏 赞(0)
本文系作者 @坚果大叔 原创发布在 卖坚果的怪叔叔。未经许可,禁止转载。
ES6入门之对象的扩展
上一篇
Node.js EventEmitter 和 Buffer
下一篇
在小程序中查看

这是个😊,挣点服务器费用😜

热门文章
是过年呀
QQ,你有多久没有打开啦!
腾讯视频VIP会员免费领取!3-31天。
暂存
小米 note3 折腾记
小程序wx.showToast真机不显示?
专题标签
agent (1) CSS (15) dom (1) Es6入门系列 (14) Git (3) html (1) iview (1) JavaScript (9) js (4) Lif (1) Node (4) pyecharts (1) Python (10) ref (1) scriptable (1) Skill (1) vsCode (1) vue (4) wordpress (2) 三月 (1) 上海 (1) 假期 (1) 其他分享 (3) 前端两三问 (15) 古镇 (1) 外滩 (1) 对象 (1) 小程序 (5) 年度总结 (6) 年终总结 (1) 微信机器人 (4) 打字机 (1) 技术 (1) 日常问题 (8) 日常问题记录 (1) 春天 (2) 服务器 (2) 海族馆 (1) 生活 (8) 网上国网 (1) 记录 (3) 通勤 (1) 重学JavaScript (11) 面试题 (10) 🌸 (1)
什么是Agent?
2026-08-15 23:49:12
429 0 2
什么是 Skill?
2026-08-12 21:32:42
348 1 0
失业在家,我给小朋友做了一个练字小程序!
2026-08-07 16:21:52
690 10 1
上线8年,15万用户的小程序,一共赚了多少钱?
2026-05-30 18:01:24
4,683 4 0
  • 0
博主

一位佛系的前端开发者,略通摄影,乐于尝试新事物,热衷于美食。

友链
故事胶片
公众号
坚果大叔 执行上下文 卖坚果的怪叔叔 Dacking
Copyright © 2017-2026 卖坚果的怪叔叔

开往-友链接力

萌ICP备20230818号

苏ICP备18048410号-3
  • 首页
  • 生活
  • 技术
  • 记录
  • 工具箱
  • 关于我
# CSS # # JavaScript # # vue # # 微信 # # 生活 #
坚果大叔
345
文章
171
评论
432
喜欢