javascript变量在原始变量更改后更改值

时间:2019-05-09 04:46:34

标签: javascript node.js

在对原始变量进行新更改后,我无法维护变量的原始值。

代码:

(...)
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
} 

预计原始变量(日期)的值将发生更改,并且正确发生,但是变量data_base和data_proposto不会保留其值

计算结束时两个变量的值都与变量日期相同

变量ca_proposto,ca_base等正确存储它们的值

有什么主意吗?

变量data_base和data_proposto的唯一交互是它们与数据变量的创建以及函数的返回

OBS:如果在重做新的计算(Illumination.calculate_N(数据))之前使用console.log()查看data_base变量的值,则该变量的值应正确显示,应尽快更改经过这些计算。

3 个答案:

答案 0 :(得分:2)

@chatnoir很好地定义了问题,但是由于以下问题,我不同意他的JSON序列化解决方案:

  

您将丢失任何没有等效类型的Javascript属性   JSON,例如Function或Infinity。分配给的任何属性   undefined将被JSON.stringify忽略,从而导致它们被遗漏   在克隆的对象上。

     

我建议执行深度复制是依靠一个很好的库   经过测试,非常受欢迎且经过精心维护的:Lodash。

Lodash提供了非常方便的克隆和深层克隆功能来执行浅层和深层克隆。

Lodash具有一个很好的功能:您可以在项目中分别导入单个函数,以减少大量依赖。

请在此处找到运行示例代码:https://glitch.com/edit/#!/flavio-lodash-clone-shallow-deep?path=server.js:1:0

答案 1 :(得分:1)

您在函数内部和外部使用了相同的变量data

ie; data在全球范围内。

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

即使您期望方法calculate_ai中的变量data的范围仅限于该方法,但事实并非如此。 data属于全局范围,因此,变量方法内部的值更改也会影响外部变量。

有效的解决方案是在方法内部使用其他变量。

答案 2 :(得分:1)

因为在两种情况下,您都不是分配当前状态下的对象本身,而是分配对该对象的引用。您需要做的就是克隆对象,以便此时冻结状态。

简单克隆(浅副本)

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

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

这里的限制是它只能进行浅表复制。有关更多说明,请参见下面的深拷贝

JSON克隆

这是克隆的一种快捷方法,因为它将JSON对象转换为字符串,然后又转换为字符串。也就是说,您不再获得参考,而是一个新对象。

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

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

但是,如果您的对象不是JSON安全对象,则此方法将无效。

深拷贝

最不优雅的方法可能是最安全的。它将属性深层复制到新对象中。与Object.assign()的主要区别在于,它复制嵌套属性的 values ,而Object.assign()将 reference 复制到嵌套对象。

因此,使用Object.assign(),嵌套对象中的任何后续更改都会影响“克隆”的所有版本。如果克隆时克隆仅具有这些嵌套对象的属性值,则不会发生这种情况–这些值不受嵌套对象的任何更改的影响。

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);