Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javascript variable changing value after changes in original variable

I am having trouble maintaining the original value of a variable after making new changes to the original variable.

Code:

(...)
data = Illumination.calculate_N(data)
data = Illumination.calculate_pi(data)
data = Illumination.calculate_kwh(data)
data = Illumination.calculate_ca(data)           

let data_base = data

let ca_base = data.ca
let kwh_base = data.kwh
let pi_base = data.pi

(...)

data = Illumination.calculate_N(data)
data = Illumination.calculate_pi(data)
data = Illumination.calculate_kwh(data)
data = Illumination.calculate_ca(data)            

let data_proposto = data

let ca_proposto = data.ca
let kwh_proposto = data.kwh
let pi_proposto = data.pi

-----------------------------------
EXAMPLE:
static calculate_ai(data){
  data.ai = data.areaTotal*data.au
  return data
} 

It was expected that the original variable (date) would have its values ​​changed, and this happens correctly, however, the variables data_base and data_proposto are not keeping their values

Both variables at the end of the calculation have the same values ​​as the variable date

The variables ca_proposto, ca_base, and the like store their values ​​correctly

Any idea?

The only interactions of the variables data_base and data_proposto were their creations with the data variable and their return of the function

OBS: If I use console.log () to view the value of the data_base variable before redoing the new calculations (Illumination.calculate_N (data)), the value of the variable appears correctly as it should, it is changed shortly after these calculations.

like image 998
João Pedro Silva Dezembro Avatar asked Mar 05 '23 00:03

João Pedro Silva Dezembro


1 Answers

Because in both cases you are assigning not the object itself in the current state, but a reference to that object. What you need to do is to clone the object so the state is frozen at that point.

Simple Clone (Shallow Copy)

let data_base = Object.assign({}, data); //you get a clone of data 

let data_proposto = Object.assign({}, data); 

The limitation here is that it only does a shallow copy. See Deep Copy below for further explanation.

JSON Clone

This is a quick-and-dirty way to clone as it converts a JSON object to a string, and then back. i.e. you are no longer getting a reference, but a new object.

let data_base = JSON.parse(JSON.stringify(data));

let data_postero = JSON.parse(JSON.stringify(data));

But this won't work if your object is not JSON-safe.

Deep Copy

The least elegant method is probably safest. It deep copies the properties over into a new object. The key difference with Object.assign() is that it copies the values of nested properties, whereas Object.assign() copies the reference to nested objects.

So with Object.assign() any subsequent changes in your nested objects will affect all versions of your "clones". This won't happen if your clones only have property values of those nested objects at the time of cloning – these values are not affected by any changes to the nested objects.

const deepCopy = function(src) {
let target = {};
// using for/in on object also returns prototype properties
for (let prop in src) {
    // .hasOwnProperty() filters out these prototype properties.
    if (src.hasOwnProperty(prop)) {
        target[prop] = src[prop]; //iteratively copies over values, not references
    }
}
return target;
}

let data_base = deepCopy(data);

let data_postero = deepCopy(data);
like image 139
chatnoir Avatar answered Apr 28 '23 03:04

chatnoir