Объединить два объектных литерала в javascript
У меня есть два объектных литерала:
var animal = {
eat: function() {
console.log("eating...");
}
}
var dog = {
eat: "this has to be replaced when merged",
nrOfLegs: 4
}
Вам нужна функция слияния:
dog = someMergingFunction(animal, dog);
Это производит:
{
eat: function() {
console.log("eating...");
},
nrOfLegs: 4
}
Один из объектных литералов должен заменить идентичные свойства.
Как это сделать в Javascript?
Ответы
Ответ 1
// usage merged = someMergingFunction(a, b, c, d, ...)
// keys in earlier args override keys in later args.
// someMergingFunction({foo:"bar"}, {foo:"baz"})
// ==> {foo:"bar"}
function someMergingFunction () {
var o = {}
for (var i = arguments.length - 1; i >= 0; i --) {
var s = arguments[i]
for (var k in s) o[k] = s[k]
}
return o
}
Ответ 2
Следующее должно работать:
function merge(obj1, obj2) {
var obj = {};
for (var x in obj1)
if (obj1.hasOwnProperty(x))
obj[x] = obj1[x];
for (var x in obj2)
if (obj2.hasOwnProperty(x))
obj[x] = obj2[x];
return obj;
}
Если оба объекта имеют одно и то же свойство, значение в obj2
имеет приоритет.
Ответ 3
Я очень рекомендую метод расширения jQuery, так как он обеспечит полную поддержку браузера.
var object = $.extend({}, object1, object2, ..., objectN);
Помните, что первым аргументом является цель. Хорошим моментом в использовании расширения является то, что, следуя коду, вы можете сделать его рекурсивным:
var object = $.extend(object, object1, object2, ..., objectN);
Дополнительную информацию см. в документации jQuery: jQuery Docs for Extend
Ответ 4
Предположим, что свойства первого параметра переопределяют свойства второго параметра (в вашем примере):
function merge(obj1, obj2) {
for(attr in obj1)
obj2[attr]=obj1[attr];
return obj2;
}
Ответ 5
Я рекомендую использовать underscore.js
, поскольку он содержит функциональные возможности для этого и всю нагрузку связанных вещей:
_.extend({name : 'moe'}, {age : 50});
=> {name : 'moe', age : 50}
http://underscorejs.org/#extend
Ответ 6
Это может привести к удалению мухи с помощью buick, но вам может быть интересно увидеть, как Dojo делает в основном то же самое в dojo.mixin
(по крайней мере, если я правильно понял вопрос).
https://github.com/dojo/dojo/blob/0dddc5a0bfe3708e4ba829434602da51cbb041b7/_base/_loader/bootstrap.js#L277-366
Основная функциональность находится в dojo._mixin
, а dojo.mixin
заставляет ее работать итеративно для нескольких объектов постепенно за один снимок.
Обратите внимание, что dojo.mixin
работает в противоположном направлении к тому, что вы намекали в своем примере.
Ответ 7
Начиная с 2017 года, я бы использовал Object.assign(foo, bar)
Ответ 8
Здесь есть несколько хороших предложений.
Я знаю, что это действительно старый вопрос, но для будущих посетителей, которые ищут немного более гибкое решение, у меня есть аналогичная функция, которую я написал, которая принимает любое количество объектов в массиве и объединяет все они вместе и возвращают один объект со свойствами всех литералов объекта в массиве.
Примечание: порядок приоритета определяется массивом. Каждый последующий объект будет перезаписывать идентичные свойства, если они существуют в предыдущих объектах. В противном случае новые свойства просто добавляются к одному возвращенному объекту.
Я надеюсь, что это поможет будущим посетителям в этом вопросе. Здесь функция очень короткая и сладкая:
var mergeObjects = function (objectsArray) {
var result = {};
for (var i = 0; i < objectsArray.length; i++) {
for (var obj in objectsArray[i]) {
if (objectsArray[i].hasOwnProperty(obj)) {
result[obj] = objectsArray[i][obj];
};
};
};
return result;
};
Вы можете использовать его следующим образом:
// Define the mergeObjects function
var mergeObjects = function (objectsArray) {
var result = {};
for (var i = 0; i < objectsArray.length; i++) {
for (var obj in objectsArray[i]) {
if (objectsArray[i].hasOwnProperty(obj)) {
result[obj] = objectsArray[i][obj];
};
};
};
return result;
};
// Define some objects to merge, keeping one property consistent so you can
// see it overwrite the old ones
var obj1 = { test1: "test", overwrite: "overwrite1" };
var obj2 = { test2: "test2", overwrite: "overwrite2" };
var obj3 = { test3: "test3", overwrite: "overwrite3" };
// Merge the objects
var newObject = mergeObjects([obj1, obj2, obj3]);
// Test the output
for (var obj in newObject){
if (newObject.hasOwnProperty(obj)){
document.body.innerHTML += newObject[obj] + "<br />";
}
}