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

Igo*_*pov 174 javascript

鉴于对象:

var firstObject = {
    key1 : 'value1',
    key2 : 'value2'
};
Run Code Online (Sandbox Code Playgroud)

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

var secondObject = {
    key1 : 'value1',
    key2 : 'value2',
    key3 : 'value3',
    key4 : 'value4'
};
Run Code Online (Sandbox Code Playgroud)

使用参考firstObject?像这样的东西:

var secondObject = {
    firstObject,
    key3 : 'value3',
    key4 : 'value4'
};
Run Code Online (Sandbox Code Playgroud)

(这不起作用......我只是为了显示我想要构建代码的大行.)

没有使用任何JavaScript框架,是否可以实现解决方案?

Mic*_*ker 200

for(var k in firstObject) secondObject[k]=firstObject[k];
Run Code Online (Sandbox Code Playgroud)

  • 你省略了一个`hasOwnProperty()`测试,事情有点继续.直到它们停止,因为随着时间的推移你的对象变得更加复杂 除此之外,它在代码的一个不相关的部分中神秘地破解,因为太多被复制了.而且你没有任何调试环境.JS很糟糕,因此谨慎编码以防止此类问题发生是谨慎的. (22认同)
  • @ BenLee,你在这里缺少的是Igor已经展示了他对它的确切用法,其中`hasOwnProperty`是无用的.虽然我发现你的指针很有用,但我认为将*any*规则应用于*any*情况是有害和不明智的.像所有这些正在进行的模式驱动的开发实践一样,所以不要把它当作个人...... (3认同)
  • 完善!!!我真的很喜欢简单,优雅,一个班轮解决方案:)谢谢...... (2认同)
  • @MichaelKrelin-hacker,您在这里缺少的是 StackOverflow 不仅仅是为了 OP 的利益。它被用作未来访问者的参考,他们的用例可能略有不同,该指针*可能*有用。 (2认同)
  • 我认为此答案需要根据以下链接进行更新:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/assign const target = {a:1,b: 2}; const source = {b:4,c:5}; const returnTarget = Object.assign(target,source); console.log(target); //预期的输出:对象{a:1,b:4,c:5} console.log(returnedTarget); //预期的输出:对象{a:1,b:4,c:5} (2认同)

The*_*per 152

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

用法很简单:

Object.assign(secondObject, firstObject);
Run Code Online (Sandbox Code Playgroud)

而已!

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

支持正在改进,最新版本的Chrome,Firefox,Opera,Safari和Edge支持它(IE显然没有支持.)也可以使用像Babel和Traceur这样的运营商.有关详细信息,请参见此处

  • +1,另一个很酷的ES6功能.当然,目前还缺乏浏览器/甚至Node.JS支持,但正如您所提到的,有可用的转换器.如果你不喜欢它们 - 垫片:https://github.com/paulmillr/es6-shim/(或独立,`Object.assign()` - 只有垫片:https://github.com/ljharb/ object.assign). (4认同)

Ben*_*Lee 86

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

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];
    }
}
Run Code Online (Sandbox Code Playgroud)

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


kin*_*ppy 79

ES6 - 传播语法:

你可以简单地使用:

const thirdObject = {
   ...firstObject,
   ...secondObject   
}
Run Code Online (Sandbox Code Playgroud)

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

  • 哇,这真的很棒:)感谢您的回答。显然,我不再需要它了(因为它已经有一段时间了),但是它可能会对其他人有所帮助。 (2认同)

bar*_*sny 49

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

Object.keys(firstObject).forEach(function(key) {
  secondObject[key] = firstObject[key];
});
Run Code Online (Sandbox Code Playgroud)

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

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

assign(secondObject, firstObject); // assign firstObject properties to secondObject
Run Code Online (Sandbox Code Playgroud)

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

幸运的是,这些古老的浏览器可以使用es5-shim,这将填充许多ES5功能(包括那两个).

(我全都是使用polyfill而不是使用酷炫的新语言功能.)

  • 看起来像是一篇经过深思熟虑的帖子给我.祝你的死灵法师徽章好运! (2认同)

Nij*_*kun 12

Necro'ing所以人们可以使用hasOwnProperty和实际对象检查找到深度复制方法:

var extend = function (original, context, key) {
  for (key in context)
    if (context.hasOwnProperty(key))
      if (Object.prototype.toString.call(context[key]) === '[object Object]')
        original[key] = extend(original[key] || {}, context[key]);
      else
        original[key] = context[key];
  return original;
};
Run Code Online (Sandbox Code Playgroud)


Pra*_*avi 10

可以使用Object.assign组合对象.它将从右到左组合并覆盖公共属性,即左侧的相同属性将被右侧覆盖.

并且在第一个中提供空对象以避免改变源对象是很重要的.源对象应该保持干净,Object.assign()因为它本身会返回一个新对象.

希望这可以帮助!

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

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

var finalObject = Object.assign({}, firstObject, secondObject)

console.log(finalObject)
Run Code Online (Sandbox Code Playgroud)


Kam*_*ski 8

kingPuppy想法和 OP 想法的改进(浅拷贝) - 我只在 OP“示例”中添加了 3 个点:)

var secondObject = {
    ...firstObject,
    key3 : 'value3',
    key4 : 'value4'
};
Run Code Online (Sandbox Code Playgroud)

var secondObject = {
    ...firstObject,
    key3 : 'value3',
    key4 : 'value4'
};
Run Code Online (Sandbox Code Playgroud)


Koo*_*Inc 5

这应该可行,在这里测试过。

var secondObject = {
    firstObject: JSON.parse(JSON.stringify(firstObject)),
    key3 : 'value3',
    key4 : 'value4'
};
Run Code Online (Sandbox Code Playgroud)

注意:这不会复制firstObject
注释 2的方法:为了在旧版浏览器中使用,您需要一个json 解析器。
注意 3:通过引用分配是一个可行的选项,特别是在firstObject包含方法的情况下。相应地调整了给定的 jsfiddle 示例


Ant*_*ley 5

使用属性扩展符号。它是在 ES2018 中添加的(数组/迭代的扩展更早,ES2015),{...firstObject} 将所有可枚举属性作为离散属性扩展。

let secondObject = {
      ...firstObject,
      key3 : 'value3',
      key4 : 'value4'
    }
Run Code Online (Sandbox Code Playgroud)