1

I'm loading in a variable from my app-config.js file and then copying it with .slice() in an attempt to prevent its state from being mutated. Much to my chagrin, the function I'm using to alter data seems to be failing to respect this attempt at avoiding mutation. mySensitivityVarskeeps changing, although I'm not quite sure how since I'm only directly acting on mySeries. Any ideas as to why this is happening? Here's the code:

    var mySeries = mySensitivityVars.slice();


//Dummy Processing Algorithm
    function myDummyAlgo(sliderIndex, newValue, range) {
         console.log(mySeries[sliderIndex].data)

        var modifier = newValue/(range/2)
        var newSeries = mySensitivityVars[sliderIndex].data.map(function(num){
            return num * modifier
        })
        console.log(newSeries)
        // mySeries[sliderIndex].data = newSeries

        // console.log(sensitivityChart.series[0].data)
        sensitivityChart.series[sliderIndex].setData(newSeries);
    };
yoursweater
  • 1,883
  • 3
  • 19
  • 41

4 Answers4

2

Slice can copy the array but any objects that are referenced inside the array are not getting copied (only a reference is copied)

1

Without seeing the contents of mySensitivityVars it's hard to tell, but my guess is you're mutating a reference to the original object rather than a duplicate object.

Do you have any objects in mySensitivityVars? If so, the corresponding objects in mySeries will be pointing to the original objects in mySensitivityVars rather than standalone duplicates, which is why you're probably seeing the mutation issues.

Faisal
  • 139
  • 7
  • [*Pass **by** reference* means something different than what you mean](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_reference). Objects are *reference-type* values, but that has nothing to do with "pass by reference". Many people are making that mistake... – Felix Kling Nov 03 '17 at 21:10
  • @FelixKling Very true. Edited accordingly. – Faisal Nov 03 '17 at 21:16
1

You should clone the array instead of copying it if you'd like it to be mutated. you can use JSON.parse(JSON.stringify(mySensitivityVars)) which is pretty fast deep cloning technic. that would ensure new objects are assigned and not copy of the references.

Almogo
  • 81
  • 2
  • 3
  • Thanks!! This ended up being an effective solution. Makes sense in light of the fact that Marcin mentioned the objects being copied were in fact references while only the array itself was a new copy. – yoursweater Nov 06 '17 at 14:02
0

When you do:

mySeries[sliderIndex].data newSeries;

The array mySeries is a copy of mySensitivityVars, but the objects in the array are not copies. Both arrays contain references to the same objects, and modifying the data property affects them both. You need to copy the objects as well:

mySeries = mySentitivyVars.map(o => Object.assign({}, o));

And if the objects contain references to other objects, you may need to do a deep copy. See What is the most efficient way to deep clone an object in JavaScript?

Barmar
  • 741,623
  • 53
  • 500
  • 612