数组的扩展(ES6)

数组平时肯定是用的比较多的,今天和大家聊一下ES6对数组的扩展,理解的东西不多,主要是比较繁琐,简单整理了一下,主要是下面的几个地方。

1. 扩展运算符

扩展运算符(spread) 是三个点(…),它如同 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。

console.log(...[2,3,4]);

该运算符主要用于函数调用。

function push(array, items) {
    array.push(...items);
    console.log(items); // items=[1, 2, 3]
    console.log(...items); // ...items = 1 2 3
}

var array = [];
var value = [1, 2, 3];
push(array, value); // array = [1, 2, 3]

再看一下下面的例子,比较一下最终array的结果。

function push(array, ...items) {
    array.push(...items);
    console.log(items); // items = [[1, 2, 3]] items.length = 1
    console.log(...items); // ...items = [1 2 3]
}

var array = [];
var value = [1, 2, 3];
push(array, value); // array = [[1, 2, 3]]

items=[1, 2, 3] 作为形参传递到实参,函数的实参采用了ES6中的rest参数,将形参的值[1, 2, 3]保存到items数组的第0项,即 items = [[1, 2, 3]] 。

然后执行 array.push(...items); ... 在这里是扩展运算符。因为 items=[[1, 2, 3]] 所以经过扩展运算后 ...items=[1, 2, 3] ,进而经过 array.push([1, 2, 3]) 后,array=[[1, 2, 3]]。

扩展运算符的应用

  1. 合并数组

    // ES5
    [1, 2, 3].concat([4, 5]);
    
    // ES6
    [1, 2, 3, ...[4, 5]]
    
  2. 与解构赋值结合

    // ES5
    a = list[0];
    rest = list.slice(1);
    
    // ES6
    [a, ...rest] = list;
    
  3. 字符串

    扩展运算符还能将字符串转为数组。

    [..."hello"] // ["h", "e", "l", "l", "o"];
    

    上面这种写法的好处是能够识别32位的 Unicode 字符。

    'x\uD842\uDFB7y'.length // 4
    

    '\uD842\uDFB7' 表示的是码点占四个字节的 '?',上面这种写法并没有识别出来 \uD842\uDFB7 表示的是一个字符。

    [...'x\uD842\uDFB7y'].length // 3
    

    利用扩展运算符就能够识别出32位的 Unicode 字符。

  4. 实现了 Iterator 接口的对象

    任何具有 Iterator 接口的对象都可以用扩展运算符转为真正的数组。

    var nodeList = document.querySelectorAll('div');
    var array = [...nodeList];
    

    nodeList 不是一个数组而是一个类似数组的对象,但是扩展运算符会将其转换为真正的数组,因为它具有 Iterator 接口。

    下面的对象看起来像是一个类数组对象,但是由于没有 Iterator 接口,所以不能利用扩展运算符将其转换为数组。

    var arrayLike = {
        "0": 'a',
        "1": 'b',
        length: 2
    };
    
    var array = [...arrayLike] // TypeError: Cannot spread non-iterator object
    
  5. Map 和 Set 结构, Generator 函数

    扩展运算符内部调用的是数据结构的 Iterator 接口,因此只要具有 Iterator 接口的对象,都可以使用扩展运算符,如 Map 结构。

    let map = new Map([
        [1, 'one'],
        [2, 'two'],
    ]);
    
    let arr = [...map.keys()]; // [1, 2, 3]
    

2. Array.from

Array,from 方法用于将两类对象转为真正的数组:类似数组的对象(array-like object) 和可遍历(iterator)的对象。

下面是将一个类似数组的对象转为真正的数组。

let arrayLike = {
  '0': 'a',
  '1': 'b',
  length: 2
};

// ES5
var arr1 = [].slice.call(arrayLike);
// ES6
var arr2 = Array.from(arrayLike);

何为类似数组对象,本质特征只有一点,即必须有 length 属性,因此任何有 length 属性的对象,都可以通过 Array.from 方法转为数组。

3. Array.of()

作用:将一组值转换为数组。

初衷: 弥补 Array 构造函数的不足。

// Array 构造函数的不足
Array() // [] 空数组
Array(3) // [, , ,]
Array(3, 11, 8) // [3, 11, 8]

可以看到Array(3) 返回的并不是 [3]。Array.of 可以做到括号中是什么数值,生成的数组中就是什么数值。

Array(3) // [3]
Array(2) // [2]

以下代码可以模拟实现 Array.of() 方法。

function Array.of() {
    return [].slice.call(arguments);
}

4. copyWithin()

**作用:**将当前数组指定位置的成员复制到其它指定的位置,然后返回当前数组,使用这个方法会修改当前数组。

Array.prototype.copyWithin(target, start = 0, end = this.length)
  • target(必选): 从该位置开始替换数据
  • start(可选): 从该位置开始读取数据
  • end(可选):到该位置前停止读取数据,注意不包括该位置。
var arr = [1, 2, 3, 4, 5];
arr.copyWithin(0, 3); // arr = [4, 5, 3, 4, 5]

5. find() 和 findIndex()

find 方法用于找到第一个符合条件的数组成员,它的参数是一个回调函数,所有的数组成员依次执行该回调函数,直到找出第一个返回值为 true 的成员,然后返回该成员,如果没有符合条件的成员,则返回undefined。

[1, 5, 10, 15].find(function (value, index, arr) {
    return value < 9;
}); // 10

findIndex 方法用法与 find 方法类似,只是返回第一个符合条件的数组成员的位置,如果所有的数组成员都不符合条件则返回 -1 。

[1, 5, 10, 15].findIndex(function (value, index, arr) {
    return value < 9;
}); // 2

这两个方法都可以发现 NaN ,弥补了数组 IndexOf 方法的不足。

6. fill()

作用: 使用给定值填充一个数组。

['a', 'b', 'c'].fill(1); // [1, 1, 1]
new Array(3).fill(1); // [1, 1, 1]

7. entries(), keys() 和 values()

ES6 提供了三个新方法: entries(),keys(),values() 来遍历数组。它们都返回一个遍历器对象,可用 for...of 循环遍历。

**区别:**keys() 是对键名的遍历,values() 是对键值的遍历, entries() 是对键值对的遍历。

// ES5
var arr = ['a', 'b', 'c'];
for (var value of arr) {
    console.log(value); // a b c
}

// ES6 遍历键值
var arr = ['a', 'b', 'c'];
for (var value of arr.values()) {
    console.log(value); // a b c
}

// ES6 遍历键名
var arr = ['a', 'b', 'c'];
for (var key of arr.keys()) {
    console.log(key); // 0 1 2
}

// ES6 遍历键值对
var arr = ['a', 'b', 'c'];
for (var [key, value] of arr.entries()) {
    console.log(key, value);
}
// 0 "a"
// 1 "b"
// 2 "c"

8. includes()

Array.prototype.includes 方法返回一个布尔值,表示某个数组是否包含给定的值,字符串的 includes 方法类似。

[1, 2, 3].includes(1); // true
[1, 2, 3].includes(4); // false
[1, 2, 3, NaN].includes(NaN); // true 可以准确判断出NaN

没有该方法之前,我们通常使用数组的 indexOf 方法检查是否包含某个值,如下面的代码所示:

var arr = [1, 2, 3, NaN];
function hasValue(arr, value) {
    if (arr.indexOf(value) === -1) {
        console.log(value + " is not in " + arr);
    } else {
        console.log(value + " is in " + arr);
    }
}
hasValue(arr, 4); // 4 is not in [1,2,3]
hasValue(arr, 1); // 1 is in [1,2,3]
hasValue(arr, NaN) // NaN is not in [1,2,3,NaN] 会对NaN造成误判

indexOf 方法有两个缺点:一是不够语义化,其含义是找到参数值第一个出现的位置,所以要比较是否不等于 -1,表达起来不够直观;二是,其内部使用严格相等运算符(===)进行判断,会导致对 NaN 的误判。

9. 数组的空位

数组的空位指数组的某个位置没有任何值,比如,Array(5) 返回的数组都是空位。

Array(5) // [, , , , ,] 返回一个具有5个空位的数组。

重点来了:

空位不是 undefined ,一个位置的值等于 undefined 依然是有值的。空位是没有任何值的,下面用 in运算符来说明这一点。

in 运算符: 如果指定的属性在指定的对象或其原型链中,则in 运算符返回true。

0 in [undefined undefined]; // true
0 in [, ,]; // false

数组是一种特殊的对象,[1 ,2, 3] 实际上就是 :

{
    "0": 1,
	"1": 2,
	"2": 3
}

0这个属性在 [undefined, undefined] 中,但是不在 [, ,] 中说明,undefined是有值的,undefined 并不是空位。

ES6 和 ES5 对空位的处理规则不太一致,总结起来就是下面的一句话:

ES5 大多数情况下会忽略空位,ES6则不会忽略空位而是遇到空位是将其转换为 undefined。

完

如有错误欢迎指正哦。

ES6对数组的扩展(简要总结)的更多相关文章

  1. ES6对数组的扩展

    ECMAScript6对数组进行了扩展,为数组Array构造函数添加了from().of()等静态方法,也为数组实例添加了find().findIndex()等方法.下面一起来看一下这些方法的用法. ...

  2. ES6 之 数组的扩展

    ES5 检测数组 let arr = [1,2,3,4] Array.isArray(arr) arr instanceof Array 转换方法 arr.toLocaleString() arr.t ...

  3. 【ES6】数组的扩展——扩展运算符

    1.扩展运算符[三个点(...)将一个数组转为用逗号分隔的参数序列] 作用:用于函数调用 function add(x, y) { return x + y; } const numbers = [2 ...

  4. 【ES6】数组的扩展

    1.Array.from(): 将伪数组对象和遍历的对象转为真数组 如果一个对象的键都是正整数或者0,并且有 Length属性,那么这个对象很想数组,称它为伪数组. 伪数组: let obj = { ...

  5. 数组的复制及ES6数组的扩展

    一.数组的复制 // alert([1,2,3]==[1,2,3]); let cc = [0,1,2]; let dd = cc; alert(dd==cc);//此时改变dd会影响cc ES5 只 ...

  6. es6数组的扩展

    数组扩展运算符 ...(三个点) const demoArr=[0,1,2,3,4] console.log(...demoArr) // 0 1 2 3 4 // 他把一个数组用逗号分隔了出来 // ...

  7. ES6的新特性(8)——数组的扩展

    数组的扩展 扩展运算符 含义 扩展运算符(spread)是三个点(...).它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列. console.log(...[1, 2, 3]) / ...

  8. ES6学习(三):数组的扩展

    chapter08 数组的扩展 8.1 扩展运算符 8.1.1 扩展运算符的含义 ... 如同rest运算符的逆运算,将一个数组转换为用逗号分隔的参数序列. console.log(...[1, 2, ...

  9. Es6学习笔记(7)----数组的扩展

    参考书<ECMAScript 6入门>http://es6.ruanyifeng.com/ 数组的扩展 1.扩展运算符:可以将数组转化成逗号隔离的单个参数...[1,2,3] //控制台运 ...

随机推荐

  1. MySQL 支持 emoji 图标存储

    在MySLQ中 UPDATA 和 INSERT 数据的时候,如果数据上面带有emoji图标,例如:?.?.? 很容易更新或者插入不成功,导致报错. 1 2 Error: ER_TRUNCATED_WR ...

  2. .NET Core 3.0之深入源码理解HealthCheck(一)

    写在前面 我们的系统可能因为正在部署.服务异常终止或者其他问题导致系统处于非健康状态,这个时候我们需要知道系统的健康状况,而健康检查可以帮助我们快速确定系统是否处于正常状态.一般情况下,我们会提供公开 ...

  3. Java多线程——线程间通信

    Java多线系列文章是Java多线程的详解介绍,对多线程还不熟悉的同学可以先去看一下我的这篇博客Java基础系列3:多线程超详细总结,这篇博客从宏观层面介绍了多线程的整体概况,接下来的几篇文章是对多线 ...

  4. Django总结目录

    Django总结目录 1. django框架简介及自定义简易版框架 2. 路由层 3. 视图层 4. 模板层 5. 模型层 5.1 基本操作 5.2 多表操作 5.3 进阶相关 6. 组件 6.1 a ...

  5. 【黑客基础】Windows PowerShell 脚本学习(上)

    视频地址:[黑客基础]Windows PowerShell 脚本学习 2019.12.05 学习笔记 1.$PSVersionTable :查看PowerShell的版本信息. 2.PowerShel ...

  6. 大白话OSI七层协议

    目录 一.物理层 二.数据链路层 2.1 以太网协议 2.2 Mac地址 2.3 广播地址 三.网络层 3.1 IP协议详解 3.1.1 IP地址的两部分 3.2 子网掩码详解 3.3 IP数据包详解 ...

  7. SDWebImage学习之 NSCache

    1.使用SDWebImage的好处 1.异步下载(避免主线程卡死) 2.做好图片缓存(这样就不需要每次都加载网络图片) 3.解决了循环利用的问题 很容易造成内存警告

  8. 常用tab选项卡代码

    <div class="box"> <ul> <li class="one">课程介绍</li> <li& ...

  9. 第四章 开始Unity Shader学习之旅(1)

    1. 一个最简单的顶点/片元着色器 现在,我们正式开始学习如何编写Unity Shader,更准确的说是,学习如何编写顶点/片元着色器 2.顶点/片元着色器的基本结构 我们在以前已经讲过了Unity ...

  10. Linux常用基本命令 (逐步添加)

    Linux jobs命令 fg , bg , jobs , & , ctrl + z都是跟系统任务有关 一.&命令 用在一个命令的最后,可以把这个命令放到后台执行 二.Ctrl + z ...