0

When I made a slice of array containig objects new array are still have references to objects in initial array. How can I make a slice with objects copies?

var obj1 = {name: 'object1'};
var obj2 = {name: 'object2'};
var array = [obj1, obj2];
var arraySlice = array.slice(0, 1);
arraySlice[0].name = 'object1RENAMED';
console.log(array[0].name);
console.log(arraySlice[0].name);

http://jsfiddle.net/eqgj873h/

Prints:

object1RENAMED
object1RENAMED
user1561346
  • 502
  • 3
  • 13
  • 28

3 Answers3

1

In our case you have the same references to values (values are objects), that's why you can change values in different arrays. You need create a deep clone/copy:

var arraySlice = JSON.parse(JSON.stringify(array.slice(0, 1)));

If you use jQuery you can do it like this

var arraySlice = $.extend(true, [], array.slice(0, 1));

Demo: http://jsfiddle.net/eqgj873h/2/

Oleksandr T.
  • 76,493
  • 17
  • 173
  • 144
1

You're making a shallow copy of the array, not a deep copy, so both arrays still refer to the same objects. You need to clone the objects as well.

var arraySlice = JSON.parse(JSON.stringify(array.slice(0, 1)));

I took this cloning code from

What is the most efficient way to deep clone an object in JavaScript?

Community
  • 1
  • 1
Barmar
  • 741,623
  • 53
  • 500
  • 612
0

Here's a recursive function (cloneObj) that may make your life easier. It uses Array.map to clone Objects within an Array on all levels.

var array = [{name: 'object1'}, {name: 'object2'}];
Helpers.log2Screen('array initially:<br>'+Object.print(array));

var arraySlice  = cloneObj(array);

// change names in clone:
arraySlice[0].name = "changed";
arraySlice[1].name = "DEMO";
arraySlice[1].addedProp = [{a: 1, b: 2}, {a: 2, b:3}];

Helpers.log2Screen('arraySlice (clone, changed):<br>'+Object.print(arraySlice));
Helpers.log2Screen('array didn\'t change, still:<br>'+Object.print(array));


function cloneObj(obj) {
    
    // clone the whole enchillada, recursive
    function clone(o, curr) {
        for (var l in o){
            if (!o.hasOwnProperty(l)) { continue; }
            if (o[l] instanceof Object) {
                curr[l] = cloneObj(o[l]);
            } else {
                curr[l] = o[l];
            }
        }
        return curr;
    }
    
    return obj instanceof Array 
             ? obj.slice().map( function (v) { return cloneObj(v); } )
             : obj instanceof Date 
               ? new Date(obj.getTime())
               : obj instanceof Object 
                 ? clone(obj, {})
                 : obj;
}
<script src="https://rawgit.com/KooiInc/Helpers/master/Helpers-min.js"></script>
KooiInc
  • 119,216
  • 31
  • 141
  • 177