0

In this code... mapObj.fetchTimeObjs should NOT change right?!?!
Somehow mapObj.fetchTimeObjs gets changed when this function is run:

function clockErasePast(){
    var now = new Date().getTime();
    var tmpFetchTimeObjs = [];
    for(var i =0; i<mapObj.fetchTimeObjs.length; i++){
        tmpFetchTimeObjs.push(mapObj.fetchTimeObjs[i]);
        if(mapObj.fetchTimeObjs[i].start < now){tmpFetchTimeObjs[i].start = now;}
    }
    return tmpFetchTimeObjs;
}
clearlight
  • 12,255
  • 11
  • 57
  • 75
rikkitikkitumbo
  • 954
  • 3
  • 17
  • 38

3 Answers3

1

tmpFetchTimeObjs[i] will contain only reference to the mapObj.fetchTimeObjs[i].

If you will change tmpFetchTimeObjs[i], the mapObj.fetchTimeObjs[i] will be changed, because you will have only one object which has two references. And if it will changed from one reference, it will be changed for the second reference too.

Let's consider an object which has two references. Here I change the object from one reference, and get the update for the second reference, because they refer to the same object.

var objA = { name: 'Bob', age: 25};
var objB = objA;

objB.age = 30;

console.log(objA.age);

To get independent object you need to create them. You can use Object.assign() function, which will copy any enumerable properties from into the destination(first parameter) object and returns it.

You can create with

var obj = Object.assign({}, mapObj.fetchTimeObjs[i]);
tmpFetchTimeObjs.push(obj);
Suren Srapyan
  • 66,568
  • 14
  • 114
  • 112
  • ok... so how do I just make a copy of it... so I can change the tmp and not mess with the original? – rikkitikkitumbo Jan 14 '17 at 10:25
  • well, godbless testing with an old crappy ipod (Object.assign doesn't seem to work in older versions of safari). This was the only solution that seems to work for everything: $.extend(true,[],mapObj.fetchTimeObjs).... found it here: http://stackoverflow.com/questions/7486085/copying-array-by-value-in-javascript – rikkitikkitumbo Jan 14 '17 at 10:56
  • 1
    Yes with jquery – Suren Srapyan Jan 14 '17 at 10:57
1

The objects you push to the new array, are the same as the original array has, so if you mutate them, that mutation is visible to both arrays. This is what is called doing a shallow copy.

You could make a copy at one deeper level, where you would also create new objects and copy the original object's properties (like start) into those new objects. This you can easily do with Object.assign:

    tmpFetchTimeObjs.push(Object.assign({}, mapObj.fetchTimeObjs[i]));

If these objects themselves have nested objects, then the problem you had would occur at deeper levels. If this is an issue, then you should look to deep clone solutions, like provided in this Q&A.

Community
  • 1
  • 1
trincot
  • 317,000
  • 35
  • 244
  • 286
0

You need to clone the TimeObjs, since variables only keep the reference to the TimeObjs. We don't know the structure of your TimeObjs, so if the TimeObjs doesn't contain other objects, Object.assign() will work, otherwise maybe you need a deep clone method, such as jQuery.extend().

Yichong
  • 707
  • 4
  • 10
  • yup! $.extend was what worked for me. array.slice() and array.splice(0) didn't: http://stackoverflow.com/questions/7486085/copying-array-by-value-in-javascript – rikkitikkitumbo Jan 14 '17 at 21:18
  • @rikkitikkitumbo Nice, but $.extend will also fail if there are private variables in your objects. – Yichong Jan 16 '17 at 03:07
  • @rikkitikkitumbo If you have the information or knowledge about how to instantiate the `TimeObjs`, you can write an custom cloner specialized in cloning the `TimeObjs`. In this way, you don't need import `jQuery` anymore. – Yichong Jan 16 '17 at 03:24