0

I figured this would be a really simple problem but I can't find an answer for it online.

So I have a variable that is created using a reference to a test object:

var param = testResults.results[1];

And I then want to override this variable's metrics object as follows:

const new_mets = { key: {
        k1: 100,
        k2: 200
      }
    }
param.metrics = new_mets;

This all works fine and my test passes as expected BUT I have now found out that the underlying testResults.results[1] is also being updated, which I don't want as I am referencing this in other tests.

Is there any means that I can just update my local params variable without updating the underlying testResults object?

nimgwfc
  • 1,294
  • 1
  • 12
  • 30
  • As you said you are creating a *reference*, ie `param` and `testresult.results[1]` are pointing to the very same location in memory. You have to create a deep clone of your object. See this question https://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-deep-clone-an-object-in-javascript – derpirscher Jul 19 '21 at 16:33

2 Answers2

3

You can create a shallow copy of an object with the spread operator .... This basically means you create a new object, with all the properties of some other object, and then override another property with whatever you want.

const param = {
  ...testResults.results[1],
  metrics: {
    key: {
      k1: 100,
      k2: 200
    }
  }
}

The result is a new object.

Note this is a shallow copy. That means only the top level properties are copied to a new object. This is fine for your example, but if you were to do:

param.metrics.key.k1 = 300

Then you are now mutating the metrics object that other objects may have a reference to.

I would read up on immutability in javascript, what it means and how you practice it.

Alex Wayne
  • 178,991
  • 47
  • 309
  • 337
0

In this case, you can create a shallow clone of the object:

var params = { ...testResults.results[2] };

In that case, you have a brand new object with the same keys and the same values. Mind that they are the exact same values, by reference. So changing e.g. param.metrics.k1 will still change the original param's metrics field (unless you've already overwritten .metrics by then).

Kelvin Schoofs
  • 8,323
  • 1
  • 12
  • 31
  • 1
    please keep in mind, that this will only clone the first level of nested values. But if you have deeper structures, the will again only be referenced to the original ... – derpirscher Jul 19 '21 at 16:36