ES6新增API(Array篇(二))

新增的原型方法

  1. Array.prototype.copyWithin
    函数类型:
    /** * @author: forceddd * @desc:将数组中的,从start位置开始至end位置(不包含end处的元素)结束的元素,进行浅复制,并从target处开始覆盖该数组。最后将修改后的数组返回 * @param {number} target 复制到数组的起始覆盖位置,默认值为0 * @param {number} start 开始复制元素的位置,默认值为0 * @param {number|undefined} end 结束复制元素的位置,默认值为数组长度 * @return {any[]} 改变之后的数组 */ (target?: number, start?: number, end?: number | undefined)=> T[]

    copyWithin将数组中的,从start位置开始至end位置(不包含end处的元素)结束的元素,进行浅复制,并从target处开始覆盖该数组。最后将修改后的原数组返回。
    //不传入参数时,都使用默认值,相当于 [1, 2, 3].copyWithin(0,0,3) //首先复制了数组中的[ 0, 3 )的部分,即[1,2,3] //然后从数组的下标0处开始覆盖,覆盖之后得到[1, 2, 3] console.log([1, 2, 3].copyWithin()); //[ 1, 2, 3 ] //从数组的下标1处开始覆盖,复制的部分为[1, 2, 3],从原数组的下标1处开始覆盖,原数组只剩余两个位置,所以结果为[ 1, 1, 2 ] console.log([1, 2, 3].copyWithin(1)); //[ 1, 1, 2 ]

    有几点需要注意的是:
    第一,copyWithin会修改原数组,返回的是修改之后的原数组,而不是创建的一个新数组。
    const arr = [1, 2, 3]; const res = arr.copyWithin(1, 0); console.log(arr === res, arr); //true [ 1, 1, 2 ]

    第二,当target>=arr.length时,不会发生复制行为,直接返回没有进行任何修改的原数组。
    const arr = [1, 2, 3]; const res = arr.copyWithin(6, 2); //返回没有进行任何修改的原数组 console.log(arr === res, arr); //true [ 1, 2, 3 ]

    第三,当targetstart或者end传入负数时,代表此时的从数组末尾开始计算,假如传入的值是-1,就代表倒数第一个元素的位置。
    const arr = [1, 2, 3]; const res = arr.copyWithin(-2, 2); //从下标2开始复制得到的复制部分为 [ 3 ] //从-2,即倒数第二个元素开始覆盖,就得到了 [1, 3, 3 ] console.log(arr === res, arr); //true [ 1, 3, 3 ]

  2. Array.prototype.fill
    函数类型:
    /** * @author: forceddd * @desc: 将数组从start位置开始至end结束(不包括end)的部分都赋值为value * @param {any} value 用来给数组中元素赋值的值 * @param {number} start 赋值的起始位置,默认为0 * @param {number} end 赋值的结束位置,默认为数组的长度 * @return {*} 返回值为赋值之后的原数组 */ (value?: any, start?: number, end?: number) => any[];

    fill 将数组从start位置开始至end结束(不包括end)的部分都赋值为value,然后将数组返回。
    console.log(Array(4).fill()); //[ undefined, undefined, undefined, undefined ] console.log(Array(4).fill(0)); //[ 0, 0, 0, 0 ] console.log(Array(4).fill(0, 1, 2)); //[ <1 empty item>, 0, <2 empty items> ]

    fillcopyWithin一样,返回的也是原数组,并且当start或者end为负数时,也是和copyWithin相同的处理方式。
    除此之外,从代码中也可以看出,fill会产生空位元素,而且如果value值为对象,则赋值时使用的是对象的引用。换句话说:
    const v = []; const arr = Array(4).fill(v); console.log(arr[0] === arr[1]); //true arr[0].push(1); console.log(arr); //[ [ 1 ], [ 1 ], [ 1 ], [ 1 ] ]

  3. Array.prototype.find
    函数类型:
    /** * @author: forceddd * @desc:找到数组中使得findFn返回值为true的第一个元素并将其返回 * @param {FindFn} findFn 数组每一项上执行的函数 * @param {any} thisArg 回调函数findFn中的this对象 * @return {*} */ (findFn: FindFn, thisArg?: any) => any; /** * @author: forceddd * @param {any} item 数组中的元素 * @param {number} index 当前元素在数组中的下标 * @param {any} arr 数组实例 * @return {boolean} */ type FindFn = (item: any, index: number, arr: any[]) => boolean;

    find会返回数组中使得回调函数返回值为true的第一个元素,如果没有这样的元素,会返回undefined
    console.log([1, 2, 3].find((v) => v >= 2)); //2

    在ES6之前,使用 indexOf方法需要进行严格匹配( ===)才能判定元素是否存在,使用 some方法虽然可以自定义比对的回调函数,但是只能返回 boolean,而不能获得元素本身。
    需要注意的是,find中回调函数的执行次数是根据数组的下标决定的,下标 [ 0 , arr.length - 1 ] 的范围都会执行一次,它不关心当前元素的值,所以在当前元素是空位元素的时候,find中的回调函数会把元素值作为undefined执行一次,这和mapforEach等函数是不同的。
    [1, , 3, 4].find((v) => console.log(v)); //1 undefined 3 4 [1, , 3, 4].map((v) => console.log(v)); //1 3 4

    另外,当find中的回调函数第一次执行时,它的执行次数 [ 0 , arr.length - 1 ] 就已经确定了,并且不会再改变。这也就意味着,假设我们要处理的数组arr长度为5,在回调函数执行的过程中,我们修改了arr,使其长度成为了10,或者我们删除了一个元素,使其长度变为4,回调函数都会执行5次。当元素被删除的情况下,回调函数在执行时访问不到该元素,会以undefined代替该元素继续执行。
    [1, 2, 3, 4].find((v, i, arr) => { //删除一个元素 i === 0 && arr.pop(); console.log({ v, i }); }); //{ v: 1, i: 0 } //{ v: 2, i: 1 } //{ v: 3, i: 2 } //{ v: undefined, i: 3 }

  4. Array.prototype.findIndex
    findIndexfind方法基本相同,只有返回值有区别,findIndex返回的是符合条件的元素下标,在没有这样的元素时,会返回-1
  5. keys,values,entries
    函数类型:
    type Keys = () => Iterator; type Values = () => Iterator; type Entries = () => Iterator;

    【ES6新增API(Array篇(二))】keysvaluesentries都不需要任何参数,返回的都是一个迭代器。不同点在于迭代器中的值分别是数组的下标、数组的元素以及数组的下标和数组元素组成的 [ i , v ] 形式的键值对。
    const it = ['a', 'b', 'c'].entries(); console.log(it.next()); //{ value: [ 0, 'a' ], done: false } console.log(it.next()); //{ value: [ 1, 'b' ], done: false } console.log(it.next()); //{ value: [ 2, 'c' ], done: false } console.log(it.next()); // { value: undefined, done: true }

    推荐阅读