JavaScript范围(将一个数组复制到另一个数组)

时间:2017-01-14 10:20:58

标签: javascript arrays

在此代码中...... 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;
}

3 个答案:

答案 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()