ES6新增API:Array篇(一)

2021年11月22日 阅读数:8
这篇文章主要向大家介绍ES6新增API:Array篇(一),主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

新增的静态函数

  1. Array.ofsegmentfault

    函数类型:数组

    //接收任意数量、任意类型的参数,返回这些参数按照传入顺序组成的数组
    (...args?:any[])=>any[];

    Array.of用于建立一个具备可变数量参数的新的数组实例。它和经过Array构造函数建立数组的不一样之处在于,当使用new Array的方式建立数组时,若是只传入了一个整数参数a,则会建立一个长度为a的数组,每一个元素都是空位(指empty,而不是undefined),而Array.of则会建立返回[ a ]dom

    console.log(Array(3)); //[ <3 empty items> ]
    console.log(Array.of(3)); // [ 3 ]

    当咱们须要根据传入的参数来建立数组时,若是使用的Array构造函数,并且没有特殊处理参数只有一个整数的状况,就会出现意料以外的状况。这种并不是逻辑上的、细节性的问题,在修复时,每每咱们也是最难以意识到的一类问题。函数

  2. Array.fromthis

    函数类型:code

    /**
     * @author: forceddd
     * @desc: 根据传入的一个伪数组或可迭代对象建立一个新的、浅拷贝的数组实例
     * @param {ArrayLike<any>|Iterable<any>} arrayLike 传入的数据源
     * @param {MapFn} mapFn 可选的映射函数,与Array.map用途相同
     * @param {any} thisArg 可选的this对象,映射函数mapFn中的this会指向该参数
     * @return {any[]} 新建立的数组
     */
    (arrayLike:  ArrayLike<any> | Iterable<any>, mapFn?: MapFn, thisArg?: any) => any[];
    
    /**
     * @author: forceddd
     * @desc: 映射回调
     * @param {any} value 数组中的元素
     * @param {number} index 元素的在数组中的下标
     * @return {any} 映射返回的值
     */
    type MapFn = (value: any, index: number) => any;

    Array.from是根据传入的一个伪数组可迭代对象建立一个新的浅拷贝的数组实例。orm

    Array.of不一样,Array.of是直接将参数做为返回值数组中的元素,而Array.from会根据传入的参数来产生返回值数组:对象

    当传入伪数组时,伪数组length会做为返回值数组的length伪数组的元素会做为返回值数组的元素。ci

    //传入了一个伪数组
    console.log(Array.from({ 0: '第一项元素', length: 2 }));//[ '第一项元素', undefined ]
    // tag属性不能转换成数组下标,被过滤掉了
    console.log(Array.from({ 0: '第一项元素', length: 2, tag: '一个字符串key' }));//[ '第一项元素', undefined ]
    //传入的是一个普通对象,既不是伪数组,也不是一个iterable对象,返回一个空数组
    console.log(Array.from({ 0: '第一项元素', tag: '一个字符串key' }));//[]

    当传入一个iterable对象参数时,好比ArraySet等,会对参数进行迭代,并将迭代获得的值做为返回值数组中的元素。v8

    console.log(Array.from([1, , 3])); //[ 1, undefined, 3 ]
    console.log(Array.from(new Set([1, , 3]))); //[ 1, undefined, 3 ]
    //传入了一个映射函数
    console.log(Array.from([1, 2, 3], (item) => 2 * item)); //[ 2, 4, 6 ]
    const obj = {
        value: 0,
        //自定义   [Symbol.iterator] ,是该对象成为iterable对象,执行获得的迭代器是它自身
        [Symbol.iterator]() {
            return this;
        },
        //value > 3 后,设置迭代状态为true,结束迭代
        next() {
            this.value++;
            return {
                value: this.value,
                done: this.value > 3,
            };
        },
    };
    //传入一个自定义的iterable
    console.log(Array.from(obj));//[ 1, 2, 3 ]

    须要注意的是,Array.from不会产生空位empty),若是传入的参数中,该位置的元素是空位empty),会使用undefined做为结果。

    当咱们须要将一个伪数组转为真正的数组,以便使用数组的map等方法时——好比进行dom操做,相较于使用[].slice.call(arrayLike)来讲(这种方法有可能产生空位empty)元素),使用Array.from无疑是一个更优雅也更简洁的方式。

  3. 为何要避免数组中的空位元素?

    在处理数组的函数中,不一样的函数对待空位元素的方式是不一样的,有些函数会忽略空位元素,好比map函数,而有些则不会忽略,好比Array.from,这就颇有可能会产生一些莫名其妙的问题。

    假如咱们须要经过变量count统计一个数组的length,这可让咱们很明显的看到空位元素的问题所在。

    当存在空位元素时:

    const empty = [1, , 3];
    let count1 = 0;
    let count2 = 0;
    empty.map(() => count1++);
    Array.from(empty, () => count2++);
    //因为map函数忽略了空位元素,因此传入的回调只执行了两次,count1的值为2
    console.log({ count1, count2 }); //{ count1: 2, count2: 3 }

    当不存在空位元素时:

    const normal = [1, undefined, 3];
    let count1 = 0;
    let count2 = 0;
    normal.map(() => count1++);
    normal.forEach(() => count2++);
    
    console.log({ count1, count2 }); //{ count1: 3, count2: 3 }