【问题标题】:How to overwrite JavaScript object values using Object()如何使用 Object() 覆盖 JavaScript 对象值
【发布时间】:2019-02-20 18:12:07
【问题描述】:

我对 JavaScript、Node 等还有些陌生,并且来自 Groovy 背景(其语法与 JavaScript 极为相似)。在 Groovy 中,我可以轻松地执行以下操作:

def myMap1 = {};
def myMap2 = {};

myMap1["key1"] = "value1";
myMap1["key2"] = "value2";
myMap1["key3"] = "value3";

myMap1.each() { key, value =>
    myMap2[key] = value;
}

这将遍历现有映射 (myMap1) 并将每个键的值复制到具有相同键名的新映射 (myMap2)。易如反掌。然而,JS 有一个原型的概念,这让我发疯了,因为你必须使用 hasOwnProperty、项目索引之类的东西,等等,它会导致很多本应非常简单的东西的代码。

查看 Object() 的 MDN 文档,看起来 JS 已经实现了一些允许开发人员访问键/值对而无需处理原型和所有这些东西的东西,并且您可以访问数据对象,而不是对象的属性。我现在有这个:

var existingData = {"foo":"thing","bar":"otherThing","baz":"whatever"};
var update = {"foo":"newStuff","bar":"thisChanged","baz":"arghh"};

for (const [ key, value ] of Object.entries(update)) {
    console.log("Old value is " + existingData[key]);
    existingData[key] = value;
    console.log("Setting " + existingData[key] + " to " + value);
}

我认为这可行,但我在控制台中得到了这个:

Old value is undefined
Setting thing to thing
Old value is undefined
Setting otherThing to otherThing
Old value is undefined
Setting whatever to whatever

看起来existingData[key] 没有引用键/值对中的键,而是引用值或什么?我如何告诉它,“对于第二个对象中的这个键名,设置这个值?”我一直在谷歌上搜索,一切要么以旧方式(使用索引)进行,要么无缘无故过于复杂。任何帮助将不胜感激。

【问题讨论】:

  • 我无法在最后一个代码中重现您的问题。我已将其更改为 sn-p,因此它可以在浏览器中运行,并且显示的结果与您报告的不同。
  • 我忘了在我的标签中添加“nodejs”,只是在问题中简单地提到了它——我很抱歉——这只是后端的东西,所以它在浏览器中可能不一样(尽管我会期望它是相同的)。
  • 看起来你已经找到了适合你的答案,但作为一个仅供参考,我在节点中得到的结果与我在浏览器中使用上述代码所做的结果完全相同。如果你得到不同的东西,那就是不同的问题。

标签: javascript arrays ecmascript-6 javascript-objects


【解决方案1】:
for (let key in map1) {
    map2[key] = map1[key];
}

顺便说一句,为什么你不使用 Object.assign(); ? (注意:它返回一个新对象)

let update = { "key1": "value1", "key2": "value2" };
let map2 = Object.assign({}, map1, update);

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

【讨论】:

  • 好吧,Object.assign(map2, map1) 会发生变异 map2 并且您不需要将其重新分配给 map2
  • Object.assign 只会浅拷贝对象
  • 它也只会复制对象的顶层
【解决方案2】:

只需使用Object.assign(map2, map1) 更新map2(将map1 的键/值复制到map2

或者你可以使用,

map2 = {...map2, ...map1} 构建一个新对象并完全替换map2

要拥有深层副本,您可以使用JSON.parse(JSON.stringify(map2)) 而不是map2,而不仅仅是第一级。如果您认为它是一个大对象并且会影响性​​能,请使用递归的嵌套实现复制! ;-)

【讨论】:

  • 使用 Object.assign 和 es6 扩展运算符只会浅拷贝对象
  • @matthew257 嗯,不是深拷贝,对于嵌套对象/数组,它只是对同一对象的引用。但我认为 OP 只关心第一级。
  • 是的,始终认为最好还是安全行事,只使用 JSON.parse(JSON.stringify(object));
  • 是的,我同意!如果需要深拷贝,最好使用JSON.parse(JSON.stringify(map2)),而不是使用map2
【解决方案3】:

你可以这样做——循环遍历一个键数组:

let myMap1 = {};
let myMap2 = {};

myMap1["key1"] = "value1";
myMap1["key2"] = "value2";
myMap1["key3"] = "value3";

// create an array of the keys in the object myMap1
let myMap1_keys = Object.keys(myMap1);

// loop through the array of object keys
for (let i = 0; i < myMap1_keys.length; i++) {
  myMap2[myMap1_keys[i]] = myMap1[myMap1_keys[i]];
}

我建议不要使用 for..in 循环,即在其他答案之一中使用的循环,因为这些循环比本机 for 循环慢(如上所述)。您可以在此处查看有关性能的一些详细信息:Comparing JavaScript loops performance (for, do while, for in)

如果您只是对复制对象感兴趣,可以这样做:

let myMap2 = JSON.parse(JSON.stringify(myMap1));

建议使用 Object.assign() 的另一个答案和建议使用 ES6 扩展运算符的另一个答案,但是这些将“浅”复制对象,这意味着对象正在使用对原始对象的引用,并且只会复制对象的顶层 -上面的方法深度复制我通常发现的对象是大多数用例所需要的,并且会复制对象的每一层。

【讨论】:

  • 这两个似乎都有效:existingData = JSON.parse(JSON.stringify(update)); existingData = Object.assign({}, update, update); 但现在我在稍后执行 .save() 时遇到错误:TypeError: existingData.save is not a function
  • .save 不是 js 函数 - 你想用 .save 做什么
  • 另外,如果您对这个答案回答了原始问题感到高​​兴,您可以将此答案标记为答案 - 勾号 - 使其显示为已解决?关于 .save 问题,最好在 StackOverFlow 上打开一个新问题
  • 这实际上是答案,因为它解决了我原来的问题并处理了浅拷贝问题,但是为了回答你的问题,.save 与 await 一起用于猫鼬的目的/MongoDB 更新,像这样:var savedOutput = await existingData.save() return savedOutput;
  • 太好了 - 您只需单击我的答案旁边的勾号,问题就会被标记为已解决。使用适当的标签(即 MongoDB)为 .save 问题打开一个新问题,并包含更多代码和背景 - 我一直使用 MongoDB,因此如果您在此处放置指向它的链接,将能够发布新问题跨度>
【解决方案4】:

您可以遍历键。检查这对你有帮助吗

var m1 = {};
let m2 = {};

m1["key1"] = "abc";
m1["key2"] = "def";
m1["key3"] = "ghi";

var m1_change_key = Object.keys(m1);

for (var i = 0; i < m1_change_key.length; i++) {
  m2[m1_change_key[i]] = m1[m1_change_key[i]];
 alert(m2[m1_change_key[i]])
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-03
    • 2020-08-19
    • 2018-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多