2010-12-01 28 views
10

Tengo dos objetos literales:Combinar dos literales de objetos en javascript

var animal = { 
    eat: function() { 
     console.log("eating..."); 
    } 
} 

var dog = { 
    eat: "this has to be replaced when merged", 
    nrOfLegs: 4 
} 

necesita una función fusión de esta manera:

dog = someMergingFunction(animal, dog); 

que produce:

{ 
    eat: function() { 
     console.log("eating..."); 
    }, 
    nrOfLegs: 4 
} 

Uno de los objetos literales tiene que reemplazar propiedades idénticas.

¿Cómo hago esto en Javascript?

+0

En su ejemplo , ¿cómo 'algunaFunción' sabría qué 'comer' conservar, y cuál descartar? – Emmett

+0

tal vez el primero sea el literal de objeto primordial. porque cuando fusionas dos objetos uno debe ganar el otro derecho – ajsie

+1

@Emmett Una opción sería suponer que el segundo parámetro pasado tiene prioridad sobre el primero. – Alex

Respuesta

5
// 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 
} 
12

El siguiente debería funcionar:

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; 
} 

Si los dos objetos tienen la misma propiedad, el valor de obj2 tiene prioridad.

3

Supongamos propiedades del primer parámetro anulará propiedades del segundo parámetro (como el ejemplo), esto va a hacer:

function merge(obj1, obj2) { 
    for(attr in obj1) 
     obj2[attr]=obj1[attr]; 
    return obj2; 
} 
1

Esto podría golpear con fuerza de una mosca con un Buick, pero es posible estar interesado en ver cómo Dojo hace básicamente lo mismo en dojo.mixin (al menos si entendí la pregunta correctamente).

https://github.com/dojo/dojo/blob/0dddc5a0bfe3708e4ba829434602da51cbb041b7/_base/_loader/bootstrap.js#L277-366

La funcionalidad básica está en dojo._mixin, mientras dojo.mixin hace que funcione de forma iterativa para múltiples objetos progresivamente en una sola toma.

Tenga en cuenta que dojo.mixin funciona en la dirección opuesta a la que insinuó en su ejemplo.

3

recomiendo el uso de underscore.js ya que contiene funcionalidad para éste una carga completa de cosas relacionadas:

_.extend({name : 'moe'}, {age : 50}); 
=> {name : 'moe', age : 50} 

http://underscorejs.org/#extend

6

le recomiendo método extend de jQuery, ya que proporcionará un soporte completo navegador.

var object = $.extend({}, object1, object2, ..., objectN); 

Recuerde que el primer argumento es el objetivo. El buen punto sobre el uso de extender es que siguiendo el código, puede hacer que se extienden de forma recursiva:

var object = $.extend(object, object1, object2, ..., objectN); 

Consulte la documentación del jQuery para obtener más información: jQuery Docs for Extend method

0

Hay algunas buenas sugerencias aquí.

Sé que esta es una pregunta muy antigua, pero para los futuros visitantes que buscan una solución un poco más flexible, tengo una función similar que escribí que acepta cualquier cantidad de objetos en una matriz y los fusiona todos juntos devuelve un solo objeto con las propiedades de todos los literales de objeto en la matriz.

Nota: el orden de precedencia está determinado por la matriz. Cada objeto subsiguiente sobrescribirá propiedades idénticas si existen en objetos anteriores. De lo contrario, las nuevas propiedades simplemente se agregan al único objeto que se devuelve.

Espero que esto ayude a los futuros visitantes a esta pregunta. Aquí está la función, muy corto y dulce:

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; 
}; 

Usted puede utilizar de esta manera:

// 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 />"; 
 
    } 
 
}