如何复制另一个对象的对象属性?
给定对象:
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' };
(这是行不通的…我只是为了表明我想如何构build代码)。
是否可以不使用任何JavaScript框架的解决scheme?
for(var k in firstObject) secondObject[k]=firstObject[k];
循环遍历第一个对象的属性,并将它们分配给第二个对象,如下所示:
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 。
从@Bardzuśny的回答中,ES6提供了一个本地解决scheme: Object.assign()
函数!
用法很简单:
Object.assign(secondObject, firstObject);
而已!
现在的支持显然很差, 只有Firefox(34+)支持开箱即用,而Chrome(45+)和Opera(32+)则需要设置“实验标志”。
支持正在改善,Chrome,Firefox,Opera,Safari和Edge的最新版本支持它(IE显然没有支持)。也有像Babel和Traceur这样的转译器。 在这里看到更多的细节。
在这里玩亡灵巫师,因为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 ,这将填补许多ES5function(包括这两个function)。
(我都是用polyfills而不是用冷静的,新的语言特性来阻止)。
根据ES6 – 扩展语法 :
你可以简单地使用:
const thirdObj = { ...secondObj, ...firstObj }
这避免了通过引用传递这些对象的问题
因此人们可以通过hasOwnProperty和实际的对象检查来find一个深层复制方法:
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; };
不幸的是,你不能在这样的对象中引用一个variables。 但是,您可以创build一个将对象的值复制到另一个对象的函数。
function extend( obj1, obj2 ) { for ( var i in obj2 ) { obj1[i] = obj2[i]; } return obj1; } var firstObject = { key1: "value1", key2: "value2" }; var secondObject = extend({ key3: "value3", key4: "value4" }, firstObject );
这应该工作,在这里testing。
var secondObject = { firstObject: JSON.parse(JSON.stringify(firstObject)), key3 : 'value3', key4 : 'value4' };
注意 :这不会复制firstObject
方法
注2 :在旧版浏览器中使用,你需要一个jsonparsing器
注3 :通过引用分配是一个可行的选项,特别是如果firstObject
包含方法。 相应地调整给定的jsfiddle示例
如果只想抓取第二个对象中存在的属性,可以使用Object.keys
来获取第一个对象的属性,可以使用两种方法:
A.)使用副作用将第一个对象的属性分配给第二个对象:
var a = {a:100, b:9000, c:300}; var b = {b:-1}; Object.keys(a).map(function(key, index) { if (typeof b[key] !== 'undefined') { console.log(key); b[key] = a[key]; } });
B.)或reduce
创build一个新的对象,并将其分配给第二个对象。 请注意,此方法会replace第二个对象在与第一个对象不匹配之前可能具有的其他属性:
var a = {a:100, b:9000, c:300}; var b = {b:-1, d:-1}; // d will be gone b = Object.keys(a).reduce(function(result, current) { if (typeof b[current] !== 'undefined') { result[current] = a[current]; } return result; }, {});
可以使用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)
我宁愿使用firstObject作为secondObject的原型,并添加属性描述符:
var secondObject = Object.create(firstObject, { key3: {value: "value3", writable: true, configurable: true, enumerable: true}, key4: {value: "value4", writable: true, configurable: true, enumerable: true} });
这当然不是一蹴而就的,但它给了你更多的控制权。 如果您对属性描述符感兴趣,build议阅读本文: http ://patrickdelancy.com/2012/09/property-descriptors-in-javascript/#comment-2062和MDN页面https://developer.mozilla。组织/ EN-US /文档/networking/的JavaScript /参考/ Global_Objects /对象/创build
您也可以只分配值并省略描述符,并使其缩短一点:
var secondObject = Object.create(firstObject, { key3: {value: "value3"} key4: {value: "value4"} });
兼容性:ECMAScript 5,所以IE9 +