数组的扩展(ES6)

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

1. 扩展运算符

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

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

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

  1. function push(array, items) {
  2. array.push(...items);
  3. console.log(items); // items=[1, 2, 3]
  4. console.log(...items); // ...items = 1 2 3
  5. }
  6. var array = [];
  7. var value = [1, 2, 3];
  8. push(array, value); // array = [1, 2, 3]

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

  1. function push(array, ...items) {
  2. array.push(...items);
  3. console.log(items); // items = [[1, 2, 3]] items.length = 1
  4. console.log(...items); // ...items = [1 2 3]
  5. }
  6. var array = [];
  7. var value = [1, 2, 3];
  8. 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. 合并数组

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

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

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

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

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

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

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

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

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

  4. 实现了 Iterator 接口的对象

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

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

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

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

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

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

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

2. Array.from

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

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

  1. let arrayLike = {
  2. '0': 'a',
  3. '1': 'b',
  4. length: 2
  5. };
  6. // ES5
  7. var arr1 = [].slice.call(arrayLike);
  8. // ES6
  9. var arr2 = Array.from(arrayLike);

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

3. Array.of()

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

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

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

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

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

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

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

4. copyWithin()

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

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

5. find() 和 findIndex()

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

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

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

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

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

6. fill()

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

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

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

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

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

  1. // ES5
  2. var arr = ['a', 'b', 'c'];
  3. for (var value of arr) {
  4. console.log(value); // a b c
  5. }
  6. // ES6 遍历键值
  7. var arr = ['a', 'b', 'c'];
  8. for (var value of arr.values()) {
  9. console.log(value); // a b c
  10. }
  11. // ES6 遍历键名
  12. var arr = ['a', 'b', 'c'];
  13. for (var key of arr.keys()) {
  14. console.log(key); // 0 1 2
  15. }
  16. // ES6 遍历键值对
  17. var arr = ['a', 'b', 'c'];
  18. for (var [key, value] of arr.entries()) {
  19. console.log(key, value);
  20. }
  21. // 0 "a"
  22. // 1 "b"
  23. // 2 "c"

8. includes()

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

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

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

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

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

9. 数组的空位

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

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

重点来了:

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

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

  1. 0 in [undefined undefined]; // true
  2. 0 in [, ,]; // false

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

  1. {
  2. "0": 1,
  3. "1": 2,
  4. "2": 3
  5. }

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. LMS自适应天线阵列设计 MATLAB

    在自适应天线课上刚刚学了LMS自适应阵,先出一个抢先版贴一下结果,抢先某个小朋友一步. 关于LMS的具体介绍,直接看wiki里的吧,解释的比书上简明:传送门:https://en.wikipedia. ...

  2. Oracle的高水位线

    一.什么是水位线 所有的oracle段都会有一个在段内容纳数据的上线,把这个上限成为“high water mark”,这是一个标记,用来说明已经有多少没有使用的数据块分配给这个段,原则上high w ...

  3. FBV与CBV 及CBV源码分析

    FBV与CBV 及CBV源码分析 FBV(Function Based View) 基于函数的视图 基于函数的视图,我们一直在用没啥好讲的,就是导入模块调用函数执行业务 CBV(Class Based ...

  4. VLAN实验5(在ensp上利用三层交换机实现VLAN间路由)

    原理概述: VLAN将一个物理的LAN在逻辑上划分成多个广播域.VLAN内的主机间可以直接通信,而VLAN间不能直接互通. 在现实网络中,经常会遇到需耍跨VLAN相互访问的情况,工程师通常会选择一些方 ...

  5. xcode8 运行项目时自己打印些东西

    使用 Xcode 8 运行工程的时候,在打印台会发现如下这些奇怪的日志输出: 2016-09-19 10:43:44.001757 Demo[7100:171568] subsystem: com.a ...

  6. 生活小插曲(长篇连载,持续更新ing)^_^

    这个帖子,长期记录一些小小的生活插曲 在北京朋友开店了-关于同学开快餐店的故事.今天下午听说这个朋友在附近开了一个店,下午5点多吧,出门去他那里去了.走路过去的.在那里聊了将近一个小时吧.对最近我们自 ...

  7. 顺序表-C语言实现

    顺序存储线性表的结构体: #define MAXSIZE 100 //数组最大长度 typedef int ElemType; //元素类型 typedef struct //定义线性表结构体 { E ...

  8. 优雅解决 SpringBoot 工程中多环境下 application.properties 的维护问题

    微信号:geekoftaste, 期待与大家一起探讨! 背景 我们知道 SpringBoot 有一个全局的配置文件 application.properties, 可以把工程里用到的占位符,第三方库的 ...

  9. Java学习笔记1(基础)

    计算机语言和Java 计算机语言主要由一些指令(包括数字.符号和语法等)组成,可以分为机器语言.汇编语言.高级语言三大类.Java是一种高级计算机语言,是一种可以编写跨平台应用软件.完全面向对象的程序 ...

  10. SpringBoot整合freemarker模板

    一.目录展示 二.导入依赖 三.application.properties配置文件 四.在src/main/resource/templates文件夹中创建HelloFreeMarker.ftl文件 ...