在对原始变量进行新更改后,我无法维护变量的原始值。
代码:
(...)
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变量的值,则该变量的值应正确显示,应尽快更改经过这些计算。
答案 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);