物尽其用的copyWithin

208 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第16天,点击查看活动详情 人类进步的过程中总会产生一个非必需品或者说是没用的工具,就像es6为Array增加的copyWithin方法,用于操作当前数组自身,用来把某些位置的元素复制并覆盖到其他位置上去,

该函数有三个参数

target:目标起始位置 start:可选 复制源的起始位置,可以省略(省略时默认为0),可以是负数,表示倒数第几个 end:可选 复制源的结束位置,可以省略(默认为该对象的length属性),如果是负数,表示倒数第几个,不包含关系 这三个参数都应该是数值,如果不是,会自动转成数值

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

掘个例子


把第6个元素(从0开始)到第8个元素(),复制并覆盖到以第1个位置开始的地方。

下面的加粗的位置是要复制的源,最终覆盖的位置是2,3。

const arr1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

arr1.copyWithin(1, 5, 7)

console.log(arr1) // [1, 6, 7, 4, 5, 6, 7, 8, 9, 10, 11]

start和end都可以是负数,负数表示从右边数过来第几个。 下面例子就是从倒数第三个开始(最后一个是-1),到倒数第二个结束,实际上选中的源数据只有一个9,要覆盖的目标就是索引为2的元素,也就是数组中第三个的3; 用9覆盖了3

const arr3 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
arr3.copyWithin(2, -3, -2)
console.log(arr3) //[1, 2, 9, 4, 5, 6, 7, 8, 9, 10, 11]

强行搞了一个应用场景,冒泡排序时使用一下如下,由此可以想到,当有多个数据替换时,可能用到这个方法,例如回溯算法将之前的替换为已经走过的标识,只是有这个想法,不一定行

var arr = [2, 4, 5, 6, 7, 9, 7, 6, 5, 4, 3, 1];

function maopao(arr) {

    var x = 0;
    var len = arr.length;
    for (var i = 0; i < len - 1; i++) {
        for (var j = 0; j < len - 1; j++) {
            x++;
            if (arr[j] > arr[j + 1]) {
                mid = arr[j];
                // 把j+1覆盖到j上,用这个替换了复制
                arr.copyWithin(j, j + 1, j + 2)
                // arr[j] = arr[j + 1];
                arr[j + 1] = mid;
            }
        }
    }
    console.log(x, '循环了几次') // 132 次
    return arr;
}
console.log(maopao(arr));

最后倔个例子

当对象中没有length时,copyWidthin是不会工作的,在工作时,会校验一下,用户的结束参数是否合法(end<this.length为合法参数,如果没有this.length也算不合法),不合法将不会做替换操作

let obj1 = {
    3: 3,
    4: 4
};
let obj2 = [].copyWithin.call(obj1, 0, 3, 5);
console.log(obj2)
// 结果还是原来对象
//{ '3': 3, '4': 4 }

上面的例子增加一个length,结果就不同了


let obj1 = {
    3: 3,
    4: 4,
    length:9
};
let obj2 = [].copyWithin.call(obj1, 0, 3, 5);
console.log(obj2)
// { '0': 3, '1': 4, '3': 3, '4': 4, length: 9 }

总结一下

这个方法还是挺牛的,有什么合适场景请推荐一下,因为好的东西不用就是浪费,总想做一点骚操作啊