如何在另一个对象中复制对象属性?

IT技术 javascript
2021-01-22 16:47:51

给定对象:

var firstObject = {
    key1 : 'value1',
    key2 : 'value2'
};

如何复制另一个对象( secondObject) 中的属性,如下所示:

var secondObject = {
    key1 : 'value1',
    key2 : 'value2',
    key3 : 'value3',
    key4 : 'value4'
};

使用对firstObject? 像这样的东西:

var secondObject = {
    firstObject,
    key3 : 'value3',
    key4 : 'value4'
};

(这不起作用......我把它放在大行中只是为了显示我想要如何构建代码)。

没有不使用任何 JavaScript 框架的解决方案

6个回答
for(var k in firstObject) secondObject[k]=firstObject[k];
@BenLee,我不是 IgorPopov ;-) 而且我不是 OP,我已经说过我觉得这个指针很有用,你的答案也是,这是我不喜欢的“你真的应该使用”部分。
2021-03-18 16:47:51
@BenLee,你在这里缺少的是伊戈尔已经展示了他对它的确切用途,但hasOwnProperty没有用。虽然我发现你的指针很有用,但我认为将任何规则应用于任何有害和不明智的情况的想法就像所有这些正在发生的模式驱动的开发实践一样,所以不要把它当作个人...
2021-03-19 16:47:51
@MichaelKrelin-hacker,您在这里缺少的是 StackOverflow 不仅仅是为了 OP 的利益。它用作未来访问者的参考,这些访问者可能有稍微不同的用例,该指针可能有用。
2021-03-24 16:47:51
你省略了一个hasOwnProperty()测试,事情还可以继续工作。直到它们停止,因为您的对象随着时间的推移变得更加复杂。除此之外,它在代码的不相关部分神秘地中断,因为复制了太多。而且您没有任何用于调试的上下文。JS 很糟糕,因此谨慎编码以防止此类问题的发生是明智的。
2021-03-24 16:47:51
我认为这个答案需要按照以下链接更新developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/... const target = { a: 1, b: 2 }; 常量源 = { b: 4, c: 5 }; const ReturnTarget = Object.assign(target, source); 控制台日志(目标);// 预期输出:Object { a: 1, b: 4, c: 5 } console.log(returnedTarget); // 预期输出:对象 { a: 1, b: 4, c: 5 }
2021-03-29 16:47:51

从@Bardzuśny 的回答中得到启发,ES6 提供了一个原生解决方案:Object.assign()函数!

用法很简单:

Object.assign(secondObject, firstObject);

而已!

现在的支持显然很差;只有 Firefox (34+) 支持开箱即用,而 Chrome (45+) 和 Opera (32+) 需要设置“实验标志”。

支持正在改进,最新版本的 Chrome、Firefox、Opera、Safari 和 Edge 都支持它(IE 显然不支持。)也可以使用转译器,如 Babel 和 Traceur。请参阅此处了解更多详情。

+1,另一个很酷的 ES6 特性。当然,目前还缺乏浏览器/甚至 Node.JS 支持,但正如您提到的,有可用的转译器。如果你不喜欢它们 - 垫片:github.com/paulmillr/es6-shim(或独立的,-onlyObject.assign()垫片:github.com/ljharb/object.assign)。
2021-03-13 16:47:51
请注意,它仅适用于 ES6.... 例如在 IE 中它不起作用。
2021-03-21 16:47:51
@Xoyce 如果您检查链接的 MDN 页面,它会明确指出“如果源值是对对象的引用,则它仅复制该引用值。” 所以它确实保留了引用,并且不复制对象。你对意外行为的警告仍然是恰当的,归结为有适当的期望。
2021-04-01 16:47:51
现在还有带有 3 个点的“扩展运算符”: thirdObject={...firstObject ,...secondObject}
2021-04-07 16:47:51
@pdem 是的 - 参见kingPuppy 的回答
2021-04-07 16:47:51

根据ES6 - 传播语法

您可以简单地使用:

const thirdObject = {
   ...firstObject,
   ...secondObject   
}

这避免了通过引用传递这些对象的问题。

此外,它还处理具有深度嵌套的对象。

+1 更酷地使用 ES6!上面引用的 MDN 文档没有提到在对象上使用扩展运算符,所以我做了一个小提琴来看看它的实际效果:es6fiddle.net/im3ifsg0
2021-03-18 16:47:51
@jaepage - 很好的评论供参考。具有简单属性名称的对象(根据原始问题)可迭代的。
2021-03-22 16:47:51
哇,这真是太棒了 :) 感谢您的回答。显然,我不再需要它(因为它是前一段时间),但它可能会帮助其他人。
2021-03-23 16:47:51
在 Chrome 中工作,这是 ES6,你目前需要 Babel 或一些 ES6 转译器。将来所有浏览器都应该支持这种语法。
2021-04-10 16:47:51

循环遍历第一个对象的属性并将它们分配给第二个对象,如下所示:

var firstObject = {
    key1 : 'value1',
    key2 : 'value2'
};

var secondObject = {
    key3 : 'value3',
    key4 : 'value4'
};

for (var prop in firstObject) {
    if (firstObject.hasOwnProperty(prop)) {
        secondObject[prop] = firstObject[prop];
    }
}

for-in环是不够的; 你需要hasOwnProperty有关原因的详细说明,请参阅http://bonsaiden.github.com/JavaScript-Garden/#object.forinloop

@RobW,我不认为 OPreference在技​​术意义上使用。我认为他只是指自然语言中的“指称”。
2021-03-13 16:47:51
@RobW:OP 实际上确实说过“复制”。
2021-04-02 16:47:51
你实际上需要if(Object.prototype.hasOwnProperty.call(firstObject, prop)){}站在更安全的一边。eslint.org/docs/rules/no-prototype-builtins
2021-04-07 16:47:51

在这里玩死灵法师,因为 ES5 给我们带来了Object.keys(),有可能使我们免于所有这些.hasOwnProperty()检查。

Object.keys(firstObject).forEach(function(key) {
  secondObject[key] = firstObject[key];
});

或者,将其包装成一个函数(有限的 lodash 的“副本” _.assign()):

function assign(object, source) {
  Object.keys(source).forEach(function(key) {
    object[key] = source[key];
  });
}

assign(secondObject, firstObject); // assign firstObject properties to secondObject

Object.keys()是相对较新的方法,最值得注意的是:在 IE < 9 中不可用。实际上同样适用于.forEach()数组方法,我用它代替了常规for循环。

幸运的是,有es5-shim可用于这些古老的浏览器,它将填充许多 ES5 功能(包括这两个)。

(我完全支持 polyfill,而不是阻止使用很酷的新语言功能。)

突然间,突然出现了 2 个反对票。打赌这些人会阅读此评论的机会很小-他们的实际原因是什么?你有什么建议可以改变/改进我的回答吗?
2021-03-13 16:47:51
这绝对值得上升到顶部,以及进一步向下(ES6)的对象传播初始化器——这看起来更清晰的箭头函数!
2021-04-05 16:47:51