在此代码中...... mapObj.fetchTimeObjs
不应该改变吗?!?!
运行此函数时,mapObj.fetchTimeObjs
以某种方式被更改:
function clockErasePast(){
var now = new Date().getTime();
var tmpFetchTimeObjs = [];
for(var i =0; i<mapObj.fetchTimeObjs.length; i++){
tmpFetchTimeObjs.push(mapObj.fetchTimeObjs[i]);
if(mapObj.fetchTimeObjs[i].start < now){tmpFetchTimeObjs[i].start = now;}
}
return tmpFetchTimeObjs;
}
答案 0 :(得分:1)
tmpFetchTimeObjs[i]
将仅包含对mapObj.fetchTimeObjs[i]
。
如果您要更改tmpFetchTimeObjs[i]
,则会更改mapObj.fetchTimeObjs[i]
,因为您只有一个对象,其中包含两个引用。如果它将从一个引用更改,它也将更改为第二个引用。
让我们考虑一个有两个引用的对象。在这里,我从一个引用更改对象,并获取第二个引用的更新,因为它们引用同一个对象。
var objA = { name: 'Bob', age: 25};
var objB = objA;
objB.age = 30;
console.log(objA.age);
要获得独立对象,您需要创建它们。您可以使用Object.assign()
函数,它将任何可枚举属性复制到目标(第一个参数)对象并返回它。
您可以使用
创建var obj = Object.assign({}, mapObj.fetchTimeObjs[i]);
tmpFetchTimeObjs.push(obj);
答案 1 :(得分:1)
您push
对新数组的对象与原始数组的对象相同,因此如果您改变它们,则两个数组都可以看到该突变。这就是所谓的浅副本。
您可以在更深层次上制作副本,您也可以在其中创建新对象并将原始对象的属性(如start
)复制到这些新对象中。您可以轻松使用Object.assign
:
tmpFetchTimeObjs.push(Object.assign({}, mapObj.fetchTimeObjs[i]));
如果这些对象本身具有嵌套对象,那么您遇到的问题将发生在更深层次。如果这是一个问题,那么您应该查看深层克隆解决方案,如此Q&A中提供的那样。
答案 2 :(得分:0)
您需要克隆TimeObjs
,因为变量只保留对TimeObjs
的引用。我们不知道TimeObjs
的结构,因此如果TimeObjs
不包含其他对象,Object.assign()
将起作用,否则您可能需要深度克隆方法,例如jQuery.extend()
。