Hello! Tell me, how can you copy an array into JavaScript so that, when you change the copy, the original does not change? For example:

a = [0, 1, 2, 3] b = clone(a) b[0] = 10 a[0] == 0 // => true 

Is it possible to implement such a clone method?

    4 answers 4

     var a = [0, 1, 2, 3] var b = a.slice(0); b[0] = 10; console.log('a: ' + a); console.log('b: ' + b); 

    slice - returns a shallow copy of a portion of an array to a new array object.

    In this case, from beginning to end


    Technically, slice is the quickest path, HOWEVER it will be even faster if you add 0 - as the beginning of the "cutting"

     myArray.slice(0); 

    faster than

     myArray.slice(); 

    .... so speak the languages%)

    • Tell me, how to do this: a = [0, 1, 2, 3] change (a) a == [1, 2] // => true a = [3, 2, 1] b = some_method (a) change (b) b == [2, 1] // => true a == [3, 2, 1] // => true - Rennorb
    • Really faster :) - Qwertiy

     var a = [0, 1, 2, 3] var b = [].concat(a) b[0] = 10 console.log(a + '\n' + b) 

       var oldArray = [0, 1, 2, 3]; var newArray = oldArray.slice(); 

        Performance measurement

        In chrome, slice(0) really a bit faster than just slice() and 2 times faster than concat . But Array.from even concat u loses 10 times - 3 seconds per million iterations o_O.

        But Edge does not think so - there concat is the fastest. And Array.from is still 10 (with a tail) times slower than concat a - 1.4 seconds.

        When you run the snippet, the browser will hang for a few seconds - this is normal.

         function test(f) { var a = [0, 1, 2, 3]; var t = performance.now(); f(a); t = performance.now() - t; console.log((""+f).match(/var b = .*$/m)[0] + " // " + t.toFixed(3) + " ms"); } test(function testSlice(a) { for (var q=0; q<1000000; ++q) { var b = a.slice(); } }); test(function testSlice0(a) { for (var q=0; q<1000000; ++q) { var b = a.slice(0); } }); test(function testConcat(a) { for (var q=0; q<1000000; ++q) { var b = [].concat(a); } }); test(function testFrom(a) { for (var q=0; q<1000000; ++q) { var b = Array.from(a); } }); test(function testAssign(a) { // Так делать не надо, просто для сравнения for (var q=0; q<1000000; ++q) { var b = Object.assign([], a); } }); test(function testDesruct(a) { for (var q=0; q<1000000; ++q) { var b = [...a]; } }); 

        • Yandex 51.0.2704.3342 x32: 149/145/294/2949 / 2342. - Qwertiy
        • Edge 38.14393.0.0, Microsoft EdgeHTML 14.14393: 156/150/120/1321/929 - Qwertiy
        • Since I scolded me in the next answer about microbench marks, I will chide here too. Browser optimizations of the js engine - they are very tricky, and such microbench marks can quite easily lie about the real performance of operations. - Duck Learns to Take Cover
        • @ Duck LEARNING, added fresh test. By the way, my slice without a zero accelerated and became faster))) How to make it work in ES5? - Qwertiy
        • Once again, let's start with the fact that you measure the operation without using the result (the first rule of benchmarks in general), for es6 constructions it is generally a “polyfill benchmark that connects to the sandbox”, well, that is, there are some numbers that say very little about what. - Duck Learns to Take Cover