javascript - 使用 map() 时克隆对象属性的最佳方法是什么?

标签 javascript ecmascript-6

我想添加一个新属性 (contactDetails.countryName) 并使用函数 map() 为存储在名为 users 的数组中的嵌套对象赋值。

我最近了解到我应该使用扩展运算符 (...) 然后创建/分配新属性以避免改变我的原始对象数组,所以我为此开发了 2 种不同的实现,但我我不太确定我正在遵循最佳实践来完成我想在语义和性能方面的工作。

在您看来,实现我想做的事情的最佳方法是什么?

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=> {

// Version 1 : using spreading operator twice 

const newUser = {
    ...user,
    contactDetails: {
      ...user.contactDetails,
      countryName: countries.find(c=> c.id == user.contactDetails.country).countryName
    }
  };  
  return newUser;
});

// Version 2: copying the original object property and using spread operator only for cloning the nested object properties

const newUser = {
    id: user.id,
    name: user.name,
    dateOfBirth: user.dateOfBirth,
    contactDetails: {
      ...user.contactDetails,
      countryName: countries.find(c=> c.id == user.contactDetails.country).countryName
    }
  };

console.log(users);
console.log(usersData);

最佳答案

您可以考虑以下方法:

  • 首先我会 Array.reduce国家Map因此您可以通过 key/value 或在本例中通过 countries.get(key) 获取它们,并避免每次都过滤该数组。

  • 您可以映射用户并为每个用户创建一个新对象。在这种情况下,我称它们为 accounts

  • 您也可以考虑使用 Object.assign

  • 请注意,... 运算符和 Object.assign 都是浅克隆方法。它们不会递归地克隆嵌套对象/子对象。为此,您可以使用 JSON.stringifyJSON.parse 等。

let countries = [
  { id: 3, countryName : "UK" },
  { id: 4, countryName : "Spain" },
  { id: 6, countryName : "Germany"}
].reduce((r,{id, countryName}) => (r.set(id, countryName), r), new Map()) // reduce with Map

let 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" } }, ];

let accounts = users.map(user => Object.assign({}, user, {  // <-- map through
  contactDetails: { 
   ...user.contactDetails,
   countryName: countries.get(user.contactDetails.country)  // <-- get by key
  }
}))

users[0].id = 2  // <-- modify users
users[0].contactDetails.phone = "00000"

console.log(users, accounts) // <-- no changes to accounts

请注意,当我们更新 users[0].idusers[0].contactDetails.phone 时,帐户值没有更新。

关于javascript - 使用 map() 时克隆对象属性的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56351476/

相关文章:

javascript - 寻找与当前正在进行的组合最接近的组合

javascript - 对象传播过滤键

javascript - 在Rails中使用ES6语法和Javascript压缩的直接,受支持的稳定方法是什么?

javascript - 当包含在自定义可折叠 div 中时,Jquery Chosen 不显示数据占位符

JavaScript promise : a problem with setTimeout inside a promise race

javascript - 如何在 KnockoutJs 中为此使用绑定(bind)处理程序

javascript - 比较和更改两个对象数组

javascript - 将对象数组减少/过滤为新的对象数组。

javascript - 为什么 Object.getPrototypeOf(instance.constructor) 不等于 instance.constructor.prototype?

包含函数参数的 Javascript 变量名