博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ES6数组的扩展
阅读量:4595 次
发布时间:2019-06-09

本文共 6846 字,大约阅读时间需要 22 分钟。

1. 扩展运算符

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

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

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

2. 扩展运算符后面还可以放置表达式

  const x = 2;

  const arr = [

    ...(x>0?['a']:[]),
    'b'
  ];

  arr  // [a, b]

  如果扩展运算符的后面是一个空数组,则不产生任何效果。

  [...[], 1]  // [1]

3. 替换函数的apply方法

  由于扩展运算符可以展开数组,所以不再需要apply方法,将数组转为函数的参数了。

  function f(x, y, z) {

    console.log(x, y, z);
  }

  const args = [0, 1, 2];

  es5: 

  f.apply(null, args);  // 0, 1, 2

  es6:

  f(...args)  // 0, 1, 2

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

  Math.max(...[5, 9, 1])  // 9

  通过push函数,将一个数组添加到另一个数组的尾部

   var arr1 = [0, 1, 2];

   var arr2 = [3, 4, 5];

  Array.prototype.push.apply(arr1, arr2);  // 6

  arr1  // [0, 1, 2, 3, 4, 5]

  ES5 写法中,push方法的参数不能是数组,所以只好通过apply方法变通使用push方法。有了扩展运算符,就可以直接将数组传入push方法。

  new (Date.bind.apply(Date, [null, 2015, 1, 1]))  // Sun Feb 01 2015 00:00:00 GMT+0800 (中国标准时间)

  new Date(...[2015, 1, 1])  // Sun Feb 01 2015 00:00:00 GMT+0800 (中国标准时间)

4. 扩展运算符的应用

  1)复制数组

    数组是复合的数据类型,直接复制的话,只是复制了指向底层数据结构的''指针'',而不是克隆一个全新的数组。

    const a1 = [1, 2];

    const a2 = a1;

    a2[0] = 2;

    a1  // [2, 2]

    a2并不是a1的克隆,而是指向同一份数据的另一个指针。修改a2,会直接导致a1的变化。

    ES5 只能用变通方法来复制数组。

    const a1 = [1, 2];

    const a2 = a1.concat();  // a2是一个新数组

    a2[0] = 2;

    a2   // [2, 2]

    a1   // [1, 2]

    上面代码中,a1会返回原数组的克隆,再修改a2就不会对a1产生影响。

    扩展运算符提供了复制数组的简便写法。

    const a1 = [1, 2];

    写法一:

    const a2 = [...a1];   

    a2  // [1, 2]

    写法二:

    const [...a2] = a1;

    a2   // [1, 2]

    上面的两种写法,a2都是a1的克隆。

  2)合并数组

    扩展运算符提供了数组合并的新写法。

    es5:

    const more = [8, 9];

    [1, 2].concat(more);  // [1, 2, 8, 9]

    es6:

    [3, 4, ...more]  // [3, 4, 8, 9]

    var a1 = ['a', 'b'];

    var a2 = ['c'];

    var a3 = ['d', 'e'];

    a1.concat(a2, a3);    // ["a", "b", "c", "d", "e"]

    [...a1, ...a2, ...a3]     // ["a", "b", "c", "d", "e"]

  3)与解构赋值结合

    扩展运算符可以与解构赋值结合起来,用于生成数组。

    const [first, ...rest] = [1, 2, 3, 4, 5];

    first    // 1

    rest    // [2, 3, 4, 5]

    const [first, ...rest] = [];

    first  // 'undefined'

    rest  // []

    const [first, ...rest] = ['foo'];

    first  // foo

    rest  // []

    如果将扩展运算符用于数组赋值,只能放在参数的最后一位,否则会报错。

  4)字符串

    扩展运算符可以将字符串转换为真正的数组

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

    let namesSet = new Set(['a', 'b']);  

    Array.from(namesSet)  // ['a', 'b']

    如果Array.from()的参数是一个数组, 则会返回一个一模一样的数组。

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

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

       对于还没有部署该方法的浏览器,可以用Array.prototype.slice方法替代。

     const toArray = ( (obj) => Array.from ? Array.from : obj => [].slice.call(obj))();

     Array.from还可以接受第二个参数,作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组。

     let arr = [1, 2, 3];

     Array.from(arr, x => x * x);  // [1, 4, 9]

    arr  // [1, 2, 3]

       将数组中布尔值为false的成员转为0

    Array.from([1, , 2, , 3], (n) => n || 0)  // [1, 0, 2, 0, 3]

    Array.prototype.slice.call(arguments)能将具有length属性的对象转成数组

    const obj = {

      '0': 'xhk',
      '1': 'coco',
      length: 2
    }

    [].slice.call(obj)  // ["xhk", "coco"]

 5. Array.of方法用于将一组值,转换为数组。  

  Array.of(2016, 8, 26);  // [2016, 8, 26]

  Array.of(3)  // [3]

  Array.of(3).length  // 1

  有当参数个数不少于 2 个时,Array()才会返回由参数组成的新数组。参数个数只有一个时,实际上是指定数组的长度。

  不存在由于参数不同而导致的重载。

     不论Array.of的参数有几个,都是返回数组。0个参数返回空数组,以此类推。

   Array.of总是返回参数值组成的数组。如果没有参数,就返回一个空数组。

 6. 数组实例的copyWithin() 

   在当前数组内部,将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组。也就是说,使用这个方法,会修改当前数组。

   Array.prototype.copyWithin(target, start = 0, end = this.length)

   target(必需):从该位置开始替换数据。如果为负值,表示倒数。

   start(可选):从该位置开始读取数据,默认为 0。如果为负值,表示倒数。

        end(可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示倒数。

   [1, 2, 3, 4, 5].copyWithin(0, 2, 4)  // [3, 4, 3, 4, 5]

   [1, 2, 3, 4, 5].copyWithin(0, 2, 3)  // [3, 2, 3, 4, 5]

   [1, 2, 3, 4, 5].copyWithin(4, -3, -2)  // [1, 2, 3, 4, 3]

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

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

  [1, 5, 10, 15].find((value, index, arr) => value > 9)  // 10 返回符合条件的数组的当前值

  find方法的回调函数可以接受三个参数,依次为当前的值、当前的位置和原数组。

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

  [1, 5, 10, 15].findIndex((value, index, arr) => value > 9)  // 2  返回的是符合条件的数组成员的位置

  [1, 5, 10, 15].findIndex((value, index, arr) => value > 20)  // -1 所有成员都不符合条件返回-1

  find(), findIndex() 都可以接受第二个参数,用来绑定回调函数的this对象。

  function f(v) {

    return v > this.age;
  }

  let xhk = {

    name: 'xhk',
    age: 36
  }

  [1, 5, 30, 60].find(f, xhk)  // 60

  Object.is(value1, value2)  比较两个数是否相同  

  参数一:需要比较的第一个数

  参数二:需要比较的第二个数

  返回值: 表示两个数是否相同的boolean

  [0, 1, 2, 3, NaN].findIndex((y) => Object.is(NaN, y))  // 4  返回符合条件的数组成员的位置

8. 数组实例的fill()

  fill方法使用给定值,填充一个数组。

  [1, 2, 3].fill('xhk')  // ["xhk", "xhk", "xhk"]

  fill方法用于空数组的初始化非常方便。数组中已有的元素,会被全部抹去。

  new Array(3).fill(7)  // [7, 7, 7]

  fill方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置。

  ['xhk', 'love', 'coco'].fill('baby', 1, 2)  // ["xhk", "baby", "coco"]

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

  entries()keys()values()——用于遍历数组。它们都返回一个遍历器对象

  可以用for...of循环进行遍历,唯一的区别是keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历。

  for(let index of ['xhk', 'coco'].keys()) {

    console.log(index);
  }

  // 0 1

  values()方法,浏览器实现的参差不齐,不建议使用

  for (let elem of ['a', 'b'].values()) {

    console.log(elem);
  }

  for (let [index, elem] of ['a', 'b'].entries()) {

    console.log(index, elem)
  }

  // 0 "a" 1 "b"

  如果不使用for...of循环,可以手动调用遍历器对象的next方法,进行遍历。

  let letter = ['a', 'b', 'c'];

  let entries = letter.entries();

  console.log(entries.next().value);  // [0, 'a']

  console.log(entries.next().value);  // [1, 'b']

  console.log(entries.next().value);  // [2, 'c']

10. 数组实例的includes()

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

  [1, 2, 3].includes(2)  // true

  [1, 2, 3].includes(6)  // false

  [1, 2, 3, NaN].includes(NaN)  // true

  该方法的第二个参数表示搜索的起始位置,默认为0。如果第二个参数为负数,则表示倒数的位置,如果这时它大于数组长度(比如第二个参数为-4,但数组长度为3),则会重置为从0开始。

  [1, 2, 3].includes(2, -1)  // false

  [1, 2, 3].includes(2, -4)  // 默认从0开始

  [NaN].includes(NaN)  // true

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

  0 in [undefined, undefined, undefined]  //true  0号位置上是否存在值

  0 in [, ,]  // false 

  ES6 则是明确将空位转为undefined

  Array.from方法会将数组的空位,转为undefined

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

  扩展运算符(...)也会将空位转为undefined。  

  [...['a', , 'b']]  // ["a", undefined, "b"]

  copyWithin()会连空位一起拷贝。

  [, 1, 2, ,,].copyWithin(2, 0)   // [, 1, , 1 ]

  fill()会将空位视为正常的数组位置。

  new Array(3).fill('a')   // ["a", "a", "a"]

  for...of循环也会遍历空位。

  let arr1 = [,,];

  for (let i of arr1) {

    console.log(1)
  }

  // 1  1

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

  [...[,'a'].entries()]  // [0, 'undefined'] [1, 'a']

  [...[,'a'].keys()]  // [0, 1]

  [,'a'].find(x => true)   // 'undefined'

  [,'a'].findIndex(x => true)  // 0

 

转载于:https://www.cnblogs.com/coco-bear/p/8317447.html

你可能感兴趣的文章
js清除浏览器缓存的几种方法
查看>>
hdu 3127(矩阵切割)
查看>>
hdu 1864(01背包)
查看>>
[stl] SGI STL的空间配置器
查看>>
【IIS】IIS中同时满足集成模式和经典模式
查看>>
使用DOM解析XML文档
查看>>
python函数参数传递总结
查看>>
java生成Https证书,及证书导入的步骤和过程
查看>>
iOS开发系列--音频播放、录音、视频播放、拍照、视频录制
查看>>
LeetCode 661. Image Smoother
查看>>
(译文)MVC通用仓储类
查看>>
《操作系统》第5章:输入/输出(I/O)管理
查看>>
Python初探第一篇-变量与基本数据类型
查看>>
快速创建SpringBoot2.x应用之工具类自动创建web应用、SpringBoot2.x的依赖默认Maven版本...
查看>>
《剑指offer》字符串中的字符替换
查看>>
PHP学习笔记(11)初探PHPcms模块开发
查看>>
【剑指Offer】44、反转单词序列
查看>>
毕业设计《项目管理》总结01
查看>>
substr 方法
查看>>
Switch to strategy
查看>>