美文网首页
ES6对数组的扩展

ES6对数组的扩展

作者: microkof | 来源:发表于2018-01-17 11:05 被阅读494次

    Array.from()

    Array.from方法用于将“类数组”对象和“可迭代”对象转为真正的数组。

    类数组对象

    下面这个对象就是类数组对象,只不过很罕见,它的唯一特征就是必须有length属性。同时它一般应该由类似于数组下标的键名,但不是必须。

    let arrayLike = {
        '0': 'a',
        '1': 'b',
        '2': 'c',
        length: 3
    };
    
    // ES5的写法
    var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']
    
    // ES6的写法
    let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']
    

    常见的类数组对象是NodeList,以及函数内部的arguments对象。Array.from都可以将它们转为真正的数组。

    let ps = document.querySelectorAll('p');
    Array.from(ps); // 真正的数组
    
    // arguments对象
    function foo() {
      var args = Array.from(arguments); // 真正的数组
      // ...
    }
    

    可迭代对象

    只要是部署了 Iterator 接口的数据结构,Array.from都能将其转为数组。

    Array.from('hello')
    // ['h', 'e', 'l', 'l', 'o']
    
    let namesSet = new Set(['a', 'b'])
    Array.from(namesSet) // ['a', 'b']
    

    上面代码中,字符串和 Set 结构都具有 Iterator 接口,因此可以被Array.from转为真正的数组。

    克隆新数组

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

    跟扩展运算符(...)的对比

    扩展运算符的介绍详见ES6的扩展运算符和剩余操作符的对比和应用

    1. 相同点,都可以将部署了 Iterator 接口的数据结构转为数组。
    2. 不同点,...不能将类数组对象转化为真正数组;Array.from()可以。

    妙用

    Array.from()可以将字符串转为数组,然后返回字符串的长度。因为它能正确处理各种 Unicode 字符,可以避免 JavaScript 将大于\uFFFF的 Unicode 字符,算作两个字符的 bug。

    function countSymbols(string) {
      return Array.from(string).length;
    }
    

    Array.of()

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

    先来看Array()方法的缺陷,参数只有1个的时候,返回的数组并不是我们想要的,Array()方法把一个参数理解为数组的长度,然后建立了3个空元素的数组,通常这没什么用。

    Array() // []
    Array(3) // [, , ,]
    Array(3, 11) // [3, 11]
    Array(3, 11, 8) // [3, 11, 8]
    

    如果采用Array.of方法,行为就统一了。

    Array.of() // []
    Array.of(3) // [3]
    Array.of(3, 11) // [3, 11]
    Array.of(3, 11, 8) // [3, 11, 8]
    

    copyWithin方法

    copyWithin方法顾名思义是内部元素复制,就是用内部一部分元素,来替换内部另一部分元素。

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

    它接受三个参数。

    • target(必需):从该位置开始替换数据。如果为负值,表示倒数。
    • start(可选):从该位置开始读取数据,默认为 0。如果为负值,表示倒数。
    • end(可选):到该位置停止读取数据,默认等于数组长度。如果为负值,表示倒数。

    举例描述最清楚了:

    [1, 2, 3, 4, 5].copyWithin(0, 3)
    // 0表示从0位开始替换数据
    // 3表示从3位开始拷贝数组,一直拷贝到末尾,所以拷贝了4,5
    // 将4,5放到0位和1位,最后就是 [4, 5, 3, 4, 5]
    
    [1, 2, 3, 4, 5].copyWithin(0, 2, 4)
    // 0表示从0位开始替换数据
    // 2表示从2位开始拷贝数组,一直拷贝到4位前,所以拷贝了3,4
    // 将3,4放到0位、1位,最后就是 [3,4, 3, 4, 5]
    
    [1, 2, 3, 4, 5].copyWithin(-1, 2, 4)
    // -1表示从右数1位,也就是最后1位开始替换数据也就是说,数字5将被替换
    // 2表示从2位开始拷贝数组,一直拷贝到4位前,所以拷贝了3,4
    // 将3,4放到右数1位,最后就是 [1,2,3,4,3]
    
    [1, 2, 3, 4, 5].copyWithin(-2, -4, -2)
    // -1表示从右数2位开始替换数据,也就是说,4,5将被替换
    // -4表示从右数4位,也就是左数1位开始拷贝数组,
    // 一直拷贝到-2位前,也就是拷贝到数字4前面,也就是包含3,所以拷贝了2,3
    // 将2,3放到右数2位,替换掉4,5,最后就是 [1,2,3,2,3]
    

    find方法和findIndex方法

    find方法

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

    find方法与filter方法的对比

    find方法只返回遇到的第一个符合条件的数组成员,filter方法会返回符合条件的所有成员组成的新数组。

    findIndex方法

    findIndex方法的用法与find方法非常类似,唯一区别是findIndex方法返回的是位置,而不是成员值。

    findIndex方法与indexOf方法的对比

    1. 不同点:findIndex方法以回调函数为参数,可以进行复杂的条件筛选,indexOf方法不接受回调函数,只接受搜索值,只有全等于,才算符合条件。
    2. 相同点:都是返回index位置。

    fill方法

    fill方法是使用给定值,无脑填充一个数组,无论数组原来是什么样子,元素一律全替换成定值。

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

    ['a', 'b', 'c'].fill(7, 1, 2) // fill方法从 1 号位开始,向原数组填充 7,到 2 号位之前结束
    // ['a', 7, 'c']
    

    新的遍历方法:entries(),keys()和values()

    ES6 提供三个新的方法——entries(),keys()和values()——用于遍历数组。它们都返回一个迭代器对象,注意,这里返回的迭代器对象并不是数组。

    keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历。

    其中,values()在chrome和Firefox中还没有实现,暂时不举例了,道理都一样。

    let a = [1,3,5].keys();
    a; // 一个迭代器对象
    a.next(); // {value: 0, done: false}
    a.next(); // {value: 1, done: false}
    a.next(); // {value: 2, done: false}
    a.next(); // {value: undefined, done: true}
    
    for (let index of ['a', 'b'].keys()) {
      console.log(index);
    }
    // 0
    // 1
    
    
    
    let b = [1,3,5].entries();
    b; // 一个迭代器对象
    b.next(); // {value: Array(2), done: false}
    b.next(); // {value: Array(2), done: false}
    b.next(); // {value: Array(2), done: false}
    b.next(); // {value: undefined, done: true}
    
    for (let [index, elem] of ['a', 'b'].entries()) {
      console.log(index, elem);
    }
    // 0 "a"
    // 1 "b"
    

    includes方法

    includes方法返回一个布尔值,表示某个数组是否包含给定的值,是ES7引入的新方法。

    includes方法跟find方法、indexOf方法的区别

    1. find方法是返回满足条件的第一个元素,使用回调函数判断。
    2. indexOf方法是返回全等条件的第一个元素的位置值,是一个整数,而且不使用回调函数。
    3. includes方法是如果有全等的元素,就返回true,否则返回false。

    所以,在流程语句中,应当优先使用includes方法。

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

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

    相关文章

      网友评论

          本文标题:ES6对数组的扩展

          本文链接:https://www.haomeiwen.com/subject/lreyoxtx.html