在 JavaScript 中复制数组的最快方法 - slice vs. 'for' 循环

Fastest way to duplicate an array in JavaScript - slice vs. 'for' loop

提问人:Marco Demaio 提问时间:10/20/2010 最后编辑:AbhishekGowda28Marco Demaio 更新时间:2/8/2023 访问量:786902

问:

为了在 JavaScript 中复制数组:以下哪项使用起来更快?

Slice方法

var dup_array = original_array.slice();

For

for(var i = 0, len = original_array.length; i < len; ++i)
   dup_array[i] = original_array[i];

我知道这两种方法都只做浅层复制:如果包含对对象的引用,则不会克隆对象,而只会复制引用,因此两个数组都将具有对相同对象的引用。 但这不是这个问题的重点。original_array

我只问速度。

JavaScript 数组重复 复制 切片

评论

5赞 EscapeNetscape 10/25/2016
jsben.ch/#/wQ9RU <= 克隆阵列的最常见方法的基准
0赞 user202729 12/6/2021
参见 javascript - Copy array by value - Stack Overflow -- (该问题中的一些答案会进行性能比较)
0赞 rybo111 6/8/2023
有没有人尝试过使用返回所需数组的特定函数进行基准测试?例如const getInitialArray = () => {return [[1, 2], [3, 4]}

答:

9赞 Margus 10/20/2010 #1

看一看:链接。这与速度无关,而是与舒适度有关。此外,正如你所看到的,你只能在基元类型上使用 slice(0)。

若要创建数组的独立副本而不是对数组的引用的副本,可以使用数组切片方法。

例:

若要创建数组的独立副本而不是对数组的引用的副本,可以使用数组切片方法。

var oldArray = ["mip", "map", "mop"];
var newArray = oldArray.slice();

要复制或克隆对象:

function cloneObject(source) {
    for (i in source) {
        if (typeof source[i] == 'source') {
            this[i] = new cloneObject(source[i]);
        }
        else{
            this[i] = source[i];
  }
    }
}

var obj1= {bla:'blabla',foo:'foofoo',etc:'etc'};
var obj2= new cloneObject(obj1);

来源:链接

评论

2赞 user113716 10/20/2010
基元类型注释也适用于问题中的循环。for
4赞 lincolnk 10/20/2010
如果我要复制一个对象数组,我希望新数组引用相同的对象,而不是克隆对象。
6赞 kyndigs 10/20/2010 #2

这取决于浏览器。如果您查看博客文章 Array.prototype.slice 与手动数组创建,就会发现每种方法的性能都有一个粗略的指南:

Enter image description here

结果:

Enter image description here

评论

1赞 lincolnk 10/20/2010
arguments不是一个合适的数组,他用来强制在集合上运行。结果可能具有误导性。callslice
0赞 kyndigs 10/20/2010
是的,我的意思是在我的帖子中提到,随着兄弟的进步,这些统计数据现在可能会发生变化,但它给出了一个大致的想法。
2赞 Florian Wendelborn 6/3/2016
@diugalde 我认为唯一可以接受将代码作为图片发布的情况是代码具有潜在危险并且不应复制粘贴。不过,在这种情况下,这是非常荒谬的。
26赞 lincolnk 10/20/2010 #3

我做了一个快速演示:http://jsbin.com/agugo3/edit

我在 Internet Explorer 8 上的结果是 156、782 和 750,这表明在这种情况下要快得多。slice

评论

2赞 Drakarah 10/12/2013
不要忘记垃圾收集器的额外费用,如果你必须非常快地做到这一点。我使用切片复制元胞自动机中每个单元格的每个相邻数组,这比重用以前的数组并复制值要慢得多。Chrome 表示,大约 40% 的总时间都花在了垃圾收集上。
903赞 Dan 12/12/2013 #4

至少有 6 种 (!) 方法可以克隆数组:

  • Array.from() 数组
  • 康卡特
  • 传播语法 (FASTEST)
  • 地图A.map(function(e){return e;});

有一个 huuuge BENCHMARKS 线程,提供以下信息:

  • 对于 Blink 浏览器来说,这是最快的方法,速度稍慢,速度慢 2.4 倍。slice()concat()while loop

  • 对于其他浏览器是最快的方法,因为这些浏览器没有针对 和 的内部优化。while loopsliceconcat

这在2016年7月仍然如此。

以下是简单的脚本,您可以将其复制粘贴到浏览器的控制台中,然后运行多次以查看图片。它们输出毫秒,越低越好。

while 循环

n = 1000*1000;
start = + new Date();
a = Array(n); 
b = Array(n); 
i = a.length;
while(i--) b[i] = a[i];
console.log(new Date() - start);

n = 1000*1000;
start = + new Date();
a = Array(n); 
b = a.slice();
console.log(new Date() - start);

请注意,这些方法将克隆 Array 对象本身,但数组内容是通过引用复制的,而不是深度克隆的。

origAr == clonedArr //returns false
origAr[0] == clonedArr[0] //returns true

评论

55赞 Dan 6/14/2014
@cept0没有情绪,只有基准 jsperf.com/new-array-vs-splice-vs-slice/31
3赞 mate64 6/14/2014
@Dan 那又怎样?您的测试用例结果:Firefox 30 nightly 仍然比 Chrome 快 ~230%。检查 V8 的源代码,你会感到惊讶(虽然......splice
5赞 gman 2/13/2015
可悲的是,对于短数组,答案却大不相同。例如,在调用每个侦听器数组之前克隆它们。这些数组通常很小,通常为 1 个元素。
8赞 wcochran 9/8/2016
你错过了这个方法:A.map(function(e){return e;});
18赞 Neonit 10/30/2016
你写的是眨眼浏览器眨眼不就是一个布局引擎,主要影响 HTML 渲染,因此不重要吗?我以为我们宁愿在这里谈论 V8、Spidermonkey 和朋友。只是一件让我感到困惑的事情。如果我错了,请开导我。
324赞 KingKongFrog 2/3/2014 #5

从技术上讲最快的方法。但是,如果添加开始索引,则速度会更快。slice0

myArray.slice(0);

myArray.slice();

https://jsben.ch/F0SZ3

评论

0赞 jave.web 5/18/2016
并且比 ?myArray.slice(0,myArray.length-1);myArray.slice(0);
11赞 Marek Marczak 1/5/2018
@jave.web您;刚刚删除了数组的最后一个元素。完整副本为 array.slice(0) 或 array.slice(0, array.length)
0赞 John Leidegren 8/13/2020
这是不正确的,至少在我的机器上,根据您自己的基准。
4赞 kschiffer 10/13/2020
链接已失效。
3赞 f2d 4/4/2021
jsben.ch/56xWo - 有时,更快,有时,两者都只是勉强如此(在 Firefox 56 和最新的 Vivaldi,基于 Chrome 中)。但总是明显变慢(除了它是 Firefox 87 中最快的)。slice()slice(0)slice(0, length)
6赞 ciembor 4/28/2014 #6

有一个更干净的解决方案:

var srcArray = [1, 2, 3];
var clonedArray = srcArray.length === 1 ? [srcArray[0]] : Array.apply(this, srcArray);

长度检查是必需的,因为当构造函数只使用一个参数调用构造函数时,它的行为会有所不同。Array

评论

2赞 Chris Wesseling 4/28/2014
但它是最快的吗?
15赞 Michael Piefel 5/26/2014
也许比语义更丰富。但实际上,应用几乎是直观的。splice()
0赞 chrismarx 3/1/2016
在 Chrome 上显示最慢的性能 - jsperf.com/new-array-vs-splice-vs-slice/113
3赞 Oriol 11/13/2016
您可以使用并忽略长度:Array.ofArray.of.apply(Array, array)
54赞 Vladimir Kharlampidi 5/6/2014 #7

深度克隆阵列或对象的最简单方法:

var dup_array = JSON.parse(JSON.stringify(original_array))

评论

75赞 Seth Holladay 10/7/2014
给初学者的重要提示:因为这依赖于 JSON,所以这也继承了它的局限性。除其他外,这意味着您的数组不能包含任何 s。在此过程中,两者都将为您转换为。其他策略,例如不会更改它们,但也不会深度克隆数组中的对象。所以有一个权衡。undefinedfunctionnullJSON.stringify(['cool','array']).slice()
35赞 Yukulélé 12/12/2015
性能非常糟糕,不能处理 DOM、date、regexp、function 等特殊对象......或原型对象。不支持循环引用。切勿使用 JSON 进行深度克隆。
20赞 Lukas Liesis 7/24/2016
最糟糕的方式!仅当某些问题所有其他问题都不起作用时才使用。它很慢,资源很密集,而且在评论中已经提到了所有 JSON 限制。无法想象它是如何获得 25 票的。
4赞 Drenai 8/7/2016
它深度复制带有基元的数组,其中属性是具有更多基元/数组的数组。为此,没关系。
6赞 Harry Stevens 7/8/2017
我在我的浏览器 (Chrome 59.0.3071.115) 中针对上面 Dan 的答案进行了测试。它比 .slice() 慢近 20 倍。n = 1000*1000; start = + new Date(); a = Array(n); var b = JSON.parse(JSON.stringify(a)) console.log(new Date() - start); // 221
190赞 Yukulélé 7/7/2015 #8

ES6 Way怎么样?

arr2 = [...arr1];

评论

28赞 CHAN 7/27/2015
如果用 Babel 转换:[].concat(_slice.call(arguments))
1赞 Sterling Archer 9/28/2016
不知道从哪里来......我认为你的 babel 输出混淆了几个不同的功能。更有可能是.argumentsarr2 = [].concat(arr1)
3赞 tsh 12/28/2016
@SterlingArcher 不同于 。 语法会将 HOLE 转换为 。例如。arr2 = [].conact(arr1)arr2 = [...arr1][...arr1]undefinedarr1 = Array(1); arr2 = [...arr1]; arr3 = [].concat(arr1); 0 in arr2 !== 0 in arr3
2赞 Harry Stevens 7/8/2017
我在我的浏览器 (Chrome 59.0.3071.115) 中针对上面 Dan 的答案进行了测试。它比 .slice() 慢 10 倍以上。n = 1000*1000; start = + new Date(); a = Array(n); b = [...a]; console.log(new Date() - start); // 168
4赞 Neurotransmitter 2/6/2019
仍然不会克隆这样的东西:.如果 的值在“duplicated”数组中更改,它将在原始数组中更改,因为它只是一个引用副本,而不是克隆。[{a: 'a', b: {c: 'c'}}]c
7赞 serv-inc 8/27/2015 #9

正如@Dan所说:“这个答案很快就会过时。使用基准测试来检查实际情况“,jsperf 有一个具体的答案,它自己没有答案: while

var i = a.length;
while(i--) { b[i] = a[i]; }

有 960,589 次/秒的操作,亚军为 578,129 次/秒,即 60%。a.concat()

这是最新的 Firefox (40) 64 位。


@aleclarson创建了一个新的、更可靠的基准。

评论

1赞 aleclarson 5/13/2018
你真的应该链接 jsperf。你正在考虑的那个是坏的,因为在每个测试用例中都会创建一个新数组,除了“while 循环”测试。
1赞 aleclarson 5/13/2018
我做了一个更准确的新jsperf:jsperf.com/clone-array-3
0赞 Peter Mortensen 10/20/2018
60%什么?速度提高 60%?
1赞 serv-inc 10/20/2018
@PeterMortensen:587192是960589的~60%(61.1...)。
5赞 Gor 11/18/2015 #10

这取决于数组的长度。如果数组长度为 <= 1,000,000,则 and 方法花费的时间大致相同。但是,当您给出更广泛的范围时,该方法就赢了。sliceconcatconcat

例如,请尝试以下代码:

var original_array = [];
for(var i = 0; i < 10000000; i ++) {
    original_array.push( Math.floor(Math.random() * 1000000 + 1));
}

function a1() {
    var dup = [];
    var start = Date.now();
    dup = original_array.slice();
    var end = Date.now();
    console.log('slice method takes ' + (end - start) + ' ms');
}

function a2() {
    var dup = [];
    var start = Date.now();
    dup = original_array.concat([]);
    var end = Date.now();
    console.log('concat method takes ' + (end - start) + ' ms');
}

function a3() {
    var dup = [];
    var start = Date.now();
    for(var i = 0; i < original_array.length; i ++) {
        dup.push(original_array[i]);
    }
    var end = Date.now();
    console.log('for loop with push method takes ' + (end - start) + ' ms');
}

function a4() {
    var dup = [];
    var start = Date.now();
    for(var i = 0; i < original_array.length; i ++) {
        dup[i] = original_array[i];
    }
    var end = Date.now();
    console.log('for loop with = method takes ' + (end - start) + ' ms');
}

function a5() {
    var dup = new Array(original_array.length)
    var start = Date.now();
    for(var i = 0; i < original_array.length; i ++) {
        dup.push(original_array[i]);
    }
    var end = Date.now();
    console.log('for loop with = method and array constructor takes ' + (end - start) + ' ms');
}

a1();
a2();
a3();
a4();
a5();

如果将 original_array 的长度设置为 1,000,000,则方法和方法花费的时间大致相同(3-4 毫秒,具体取决于随机数)。sliceconcat

如果将 original_array 的长度设置为 10,000,000,则该方法将花费 60 毫秒以上,该方法将花费 20 毫秒以上。sliceconcat

评论

0赞 4esn0k 9/5/2017
dup.push是错误的,而应改用a5dup[i] =
6赞 martinedwards 1/21/2016 #11

请记住,.slice() 不适用于二维数组。您需要如下函数:

function copy(array) {
  return array.map(function(arr) {
    return arr.slice();
  });
}

评论

4赞 Aloso 1/5/2017
在 Javascript 中,没有二维数组。只有包含数组的数组。您要做的是问题中不需要的深度复制
21赞 Redu 5/29/2016 #12

a.map(e => e)是这项工作的另一种选择。截至今天,在Firefox中非常快(几乎和一样快),但在Chrome中却没有。.map().slice(0)

另一方面,如果数组是多维的,由于数组是对象,而对象是引用类型,因此没有一个切片或concat方法可以解决...因此,克隆阵列的一种正确方法是以下发明。Array.prototype.clone()

Array.prototype.clone = function(){
  return this.map(e => Array.isArray(e) ? e.clone() : e);
};

var arr = [ 1, 2, 3, 4, [ 1, 2, [ 1, 2, 3 ], 4 , 5], 6 ],
    brr = arr.clone();
brr[4][2][1] = "two";
console.log(JSON.stringify(arr));
console.log(JSON.stringify(brr));

评论

0赞 GBMan 4/25/2020
不错,但不幸的是,如果您的数组中有 Object,这将不起作用:\在这种情况下,JSON.parse(JSON.stringify(myArray)) 效果更好。
36赞 Sajjad Shirazi 10/5/2016 #13
var cloned_array = [].concat(target_array);

评论

4赞 Jed Fox 10/6/2016
请解释一下这是做什么的。
13赞 brandonscript 10/6/2016
虽然此代码片段可以回答这个问题,但它没有提供任何上下文来解释如何或为什么。不妨添加一两句话来解释你的答案。
41赞 EscapeNetscape 10/25/2016
我讨厌这种评论。它的作用是显而易见的!
7赞 Achim 12/9/2016
简单问题的简单答案,没有大故事可读。我喜欢这种答案+1
23赞 TamusJRoyce 1/9/2017
“我只问速度”——这个答案没有给出速度的指示。这是被问到的主要问题。Brandonscript 说得很有道理。需要更多的信息来考虑这个问题的答案。但如果这是一个更简单的问题,这将是一个很好的答案。
2赞 Caio Santos 8/16/2017 #14

一个简单的解决方案:

original = [1,2,3]
cloned = original.map(x=>x)
8赞 Marian07 12/16/2017 #15

ECMAScript 2015 与操作员的方式:Spread

基本示例:

var copyOfOldArray = [...oldArray]
var twoArraysBecomeOne = [...firstArray, ..seccondArray]

在浏览器控制台中尝试:

var oldArray = [1, 2, 3]
var copyOfOldArray = [...oldArray]
console.log(oldArray)
console.log(copyOfOldArray)

var firstArray = [5, 6, 7]
var seccondArray = ["a", "b", "c"]
var twoArraysBecomOne = [...firstArray, ...seccondArray]
console.log(twoArraysBecomOne);

引用

评论

0赞 XT_Nova 1/26/2018
可能唯一快速传播的就是输入它。它的性能不如其他方法。
3赞 Marian07 1/26/2018
请提供一些关于你的论点的链接。
46赞 Lior Elrom 10/22/2018 #16

🏁 克隆阵列的最快方法

我制作了这个非常简单的实用函数来测试克隆数组所需的时间。它不是 100% 可靠的,但它可以让您大致了解克隆现有阵列需要多长时间:

function clone(fn) {
  const arr = [...Array(1000000)];
  console.time('timer');
  fn(arr);
  console.timeEnd('timer');
}

并测试了不同的方法:

1)   5.79ms -> clone(arr => Object.values(arr));
2)   7.23ms -> clone(arr => [].concat(arr));
3)   9.13ms -> clone(arr => arr.slice());
4)  24.04ms -> clone(arr => { const a = []; for (let val of arr) { a.push(val); } return a; });
5)  30.02ms -> clone(arr => [...arr]);
6)  39.72ms -> clone(arr => JSON.parse(JSON.stringify(arr)));
7)  99.80ms -> clone(arr => arr.map(i => i));
8) 259.29ms -> clone(arr => Object.assign([], arr));
9) Maximum call stack size exceeded -> clone(arr => Array.of(...arr));

更新

  1. 测试是在 2018 年进行的,所以今天你很可能会得到与当前浏览器不同的结果。
  2. 在所有这些方法中,深度克隆数组的唯一方法是使用 。

    也就是说,如果您的数组可能包含函数,请不要使用上述函数,因为它将返回 .
    感谢@GilEpshtain提供此更新
    JSON.parse(JSON.stringify(arr))null

评论

6赞 mesqueeb 2/25/2019
我试着对你的答案进行基准测试,我得到了非常不同的结果:jsben.ch/o5nLG
0赞 Lior Elrom 2/25/2019
@mesqueeb,测试可能会发生变化,当然这取决于您的机器。但是,请随时使用您的测试结果更新答案。干得好!
1赞 Gil Epshtain 2/26/2019
我非常喜欢你的答案,但是我尝试了你的测试,结果是最快的。arr => arr.slice()
2赞 Gil Epshtain 2/26/2019
@LiorElrom,由于方法不可序列化,您的更新不正确。例如:将输出JSON.parse(JSON.stringify([function(){}]))[null]
2赞 edufinn 4/23/2020
不错的基准。我已经在我的 Mac 上用 2 个浏览器测试了这一点:Chrome 版本 81.0.4044.113 和 Safari 版本 13.1 (15609.1.20.111.8) 和最快的是传播操作:在 Chrome 和 Safari 中。Chrome 中的第二个快速是切片功能,在 Safari 中第二个是 .[...arr]4.653076171875ms8.565msarr.slice()6.162109375ms[].concat(arr)13.018ms
3赞 Anki 6/8/2019 #17
        const arr = ['1', '2', '3'];

         // Old way
        const cloneArr = arr.slice();

        // ES6 way
        const cloneArrES6 = [...arr];

// But problem with 3rd approach is that if you are using muti-dimensional 
 // array, then only first level is copied

        const nums = [
              [1, 2], 
              [10],
         ];

        const cloneNums = [...nums];

// Let's change the first item in the first nested item in our cloned array.

        cloneNums[0][0] = '8';

        console.log(cloneNums);
           // [ [ '8', 2 ], [ 10 ], [ 300 ] ]

        // NOOooo, the original is also affected
        console.log(nums);
          // [ [ '8', 2 ], [ 10 ], [ 300 ] ]

因此,为了避免这些情况的发生,请使用

        const arr = ['1', '2', '3'];

        const cloneArr = Array.from(arr);

评论

0赞 Aditya M P 7/18/2019
指出示例中的更改如何将更改传播到是有效的 - 但那是因为 实际上是一个对象,其引用被扩展运算符复制到其中。也就是说,这种行为不会影响我们按值(int、string 等字面量)复制的代码。cloneNums[0][0]nums[0][0]nums[0][0]cloneNums
7赞 Zibri 8/29/2019 #18

基准时间!

function log(data) {
  document.getElementById("log").textContent += data + "\n";
}

benchmark = (() => {
  time_function = function(ms, f, num) {
    var z = 0;
    var t = new Date().getTime();
    for (z = 0;
      ((new Date().getTime() - t) < ms); z++)
      f(num);
    return (z)
  }

  function clone1(arr) {
    return arr.slice(0);
  }

  function clone2(arr) {
    return [...arr]
  }

  function clone3(arr) {
    return [].concat(arr);
  }

  Array.prototype.clone = function() {
    return this.map(e => Array.isArray(e) ? e.clone() : e);
  };

  function clone4(arr) {
    return arr.clone();
  }


  function benchmark() {
    function compare(a, b) {
      if (a[1] > b[1]) {
        return -1;
      }
      if (a[1] < b[1]) {
        return 1;
      }
      return 0;
    }

    funcs = [clone1, clone2, clone3, clone4];
    results = [];
    funcs.forEach((ff) => {
      console.log("Benchmarking: " + ff.name);
      var s = time_function(2500, ff, Array(1024));
      results.push([ff, s]);
      console.log("Score: " + s);

    })
    return results.sort(compare);
  }
  return benchmark;
})()
log("Starting benchmark...\n");
res = benchmark();

console.log("Winner: " + res[0][0].name + " !!!");
count = 1;
res.forEach((r) => {
  log((count++) + ". " + r[0].name + " score: " + Math.floor(10000 * r[1] / res[0][1]) / 100 + ((count == 2) ? "% *winner*" : "% speed of winner.") + " (" + Math.round(r[1] * 100) / 100 + ")");
});
log("\nWinner code:\n");
log(res[0][0].toString());
<textarea rows="50" cols="80" style="font-size: 16; resize:none; border: none;" id="log"></textarea>

自您单击按钮以来,基准测试将运行 10 秒。

我的结果:

Chrome(V8 引擎):

1. clone1 score: 100% *winner* (4110764)
2. clone3 score: 74.32% speed of winner. (3055225)
3. clone2 score: 30.75% speed of winner. (1264182)
4. clone4 score: 21.96% speed of winner. (902929)

Firefox(SpiderMonkey 引擎):

1. clone1 score: 100% *winner* (8448353)
2. clone3 score: 16.44% speed of winner. (1389241)
3. clone4 score: 5.69% speed of winner. (481162)
4. clone2 score: 2.27% speed of winner. (192433)

优胜者代码:

function clone1(arr) {
    return arr.slice(0);
}

获胜者引擎:

蜘蛛猴 (Mozilla/Firefox)

1赞 DevLoverUmar 12/26/2019 #19

在 JavaScript 中按顺序复制数组的快速方法:

#1: array1copy = [...array1];

#2: array1copy = array1.slice(0);

#3: array1copy = array1.slice();

如果您的数组对象包含一些 JSON 不可序列化的内容(函数、Number.POSITIVE_INFINITY等),则最好使用

array1copy = JSON.parse(JSON.stringify(array1))

1赞 Shuvro 3/15/2020 #20

您可以按照此代码进行操作。不可变的数组克隆方式。这是阵列克隆的完美方式


const array = [1, 2, 3, 4]

const newArray = [...array]
newArray.push(6)
console.log(array)
console.log(newArray)
4赞 balfonso 5/15/2020 #21

在 ES6 中,您可以简单地使用 Spread 语法

例:

let arr = ['a', 'b', 'c'];
let arr2 = [...arr];

请注意,spread 运算符会生成一个全新的数组,因此修改一个数组不会影响另一个数组。

例:

arr2.push('d') // becomes ['a', 'b', 'c', 'd']
console.log(arr) // while arr retains its values ['a', 'b', 'c']
1赞 nologin 8/26/2020 #22

如果您想要在 JS 中使用 REAL 克隆对象/数组,其中包含所有属性和子对象的克隆引用:

export function clone(arr) {
    return JSON.parse(JSON.stringify(arr))
}

所有其他操作都不会创建克隆,因为它们只是更改根元素的基址,而不是包含的对象的基址。

除非你通过对象树递归遍历。

对于简单的副本,这些是可以的。对于与存储地址相关的操作,我建议(在大多数其他情况下,因为这很快!)键入 convert 成字符串,然后在一个全新的对象中返回。

18赞 Aayush Bhattacharya 2/12/2021 #23

克隆对象数组的最快方法是使用扩展运算符

var clonedArray=[...originalArray]
or
var clonedArray = originalArray.slice(0); //with 0 index it's little bit faster than normal slice()

但是克隆的数组中的对象仍将指向旧的内存位置。因此,对 clonedArray 对象的更改也会更改 orignalArray。所以

var clonedArray = originalArray.map(({...ele}) => {return ele})

这不仅会创建新的数组,还会将对象克隆到其中。

免责声明:如果您使用的是嵌套对象,在这种情况下,spread 运算符将用作 SHALLOW CLONE。在这一点上最好使用

var clonedArray=JSON.parse(JSON.stringify(originalArray));

评论

1赞 JRichardsz 2/7/2022
您是唯一注意到内存位置的人。加分!!
0赞 herrstrietzel 8/26/2022
非常感谢您强调内存位置。实际上,这可能是您需要“解耦”阵列克隆的主要原因。
1赞 T.J. Crowder 2/8/2023
JSON.parse(JSON.stringify(x))总是一个坏主意。它是有损的,如果你试图克隆结构化信息,那么在文本中来回走动是没有意义的。
3赞 MVS KIRAN 6/20/2021 #24

有几种方法可以克隆数组。基本上,克隆分为两种方式:

  1. 浅拷贝
  2. 深拷贝

浅拷贝仅覆盖阵列的第一层,其余部分是 引用。如果你想要数组中嵌套元素的真实副本,你需要一个 深度克隆。

例:

const arr1 = [1,2,3,4,5,6,7]           
// Normal Array (shallow copy is enough)     
const arr2 = [1,2,3,[4],[[5]],6,7]          
// Nested Array  (Deep copy required) 


Approach 1 : Using (...)Spread Operator  (Shallow copy enough)
const newArray = [...arr1] // [1,2,3,4,5,6,7]

Approach 2 : Using Array builtIn Slice method (Deep copy)  
const newArray = arr1.slice()  // [1,2,3,4,5,6,7]

Approach 3 : Using Array builtIn Concat method (Deep a copy)
const newArray = [].concat(arr1)  // [1,2,3,4,5,6,7]

Approach 4 : Using JSON.stringify/parse. (Deep a copy & fastest)
const newArray = JSON.parse(JSON.stringify(arr2));)  // [1,2,3,[4],[[5]],6,7]

Approach 5: Using own recursive function or using loadash's __.cloneDeep method. (Deep copy)
0赞 shashank 5/14/2022 #25

如果您正在获取 about slice,则用于从数组中复制元素并创建具有相同编号的克隆。元素或更少。的元素。

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

function slc() {
  var sliced = arr.slice(0, 5);
// arr.slice(position to start copying master array , no. of items in new array)
  console.log(sliced);
}
slc(arr);