为什么map()使嵌套数组中的原始对象发生变异?

时间:2019-05-28 21:12:54

标签: javascript ecmascript-6 array.prototype.map

我正在尝试使用map()创建一个新的对象数组(usersData),以便添加一个新属性,该新属性分配有来自辅助数组(国家/地区)的值。 在测试过程中,我注意到我的对象(用户)原始数组已被修改,新属性(countryName)已添加到其中。当我使用地图为阵列国家创建对象的新阵列时,也没有发生同样的事情。 有人可以告诉我是什么原因造成的,并帮助我了解如何避免这种行为吗?

const countries = [
  { id: 3, countryName : "UK" },
  { id: 4, countryName : "Spain" },
  { id: 6, countryName : "Germany"}
];

const users = [
  { id : 1,
    name: "Douglas Camp",
    dateOfBirth: "23-06-1984",
    contactDetails:
      {
        country: 3,
        phone: "7373724997"
      }
  },
  {
    id : 2,
    name: "Martin Stein",
    dateOfBirth: "19-08-1992",
    contactDetails:
      {
        country: 6,
        phone: "3334343434"
      }
  },
];

const usersData = users.map(user=> {
  const newUser = {};
  newUser.name = user.name;
  newUser.contactDetails = user.contactDetails;
  newUser.contactDetails.countryName = "UK";
  return newUser;
});

const countriesData = countries.map(country =>
  {
    const newCountry = {};
    newCountry.name = country.countryName;
    newCountry.continent = "Europe";
    return newCountry;
});
console.log(countries);  
console.log(countriesData); 
console.log(users);
console.log(usersData);

我希望数组用户中的元素保持其原始结构,但是现在属性contactDetails.countryName设置为“ UK”

2 个答案:

答案 0 :(得分:2)

users.map()的每次迭代中,user.contactDetails包含对要存储在新object中的newUser.contactDetails的引用。因此,两者都将引用内存中的同一对象。对于您的特殊情况,您可以解决将user.contactDetails扩展到新对象中的问题(就像克隆它的方法一样)。但是请注意,这仅适用于1-level深对象。如果您的结构更复杂,则应搜索deep-cloning

const countries = [{id:3,countryName:"UK"},{id:4,countryName:"Spain"},{id:6,countryName:"Germany"}];

const users = [{id :1,name:"Douglas Camp",dateOfBirth:"23-06-1984",contactDetails:{country:3,phone:"7373724997"}},{id :2,name:"Martin Stein",dateOfBirth:"19-08-1992",contactDetails:{country:6,phone:"3334343434"}},];

const usersData = users.map(user =>
{
    const newUser = {};
    newUser.name = user.name;
    newUser.contactDetails = {...user.contactDetails};
    newUser.contactDetails.countryName = "UK";
    return newUser;
});

const countriesData = countries.map(country =>
{
    const newCountry = {};
    newCountry.name = country.countryName;
    newCountry.continent = "Europe";
    return newCountry;
});

console.log("countries:", countries);  
console.log("countriesData:",countriesData); 
console.log("users:", users);
console.log("usersData:", usersData);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

答案 1 :(得分:1)

您正在构建一个新阵列。这并不意味着您也在构建阵列内部的所有新事物。

此:

calculateShortestPathFromSource()

正在重用原始数组元素中的newUser.contactDetails = user.contactDetails; 对象,因此:

user.contactDetails

正在修改新数组和旧数组之间共享的对象。