2010-12-01 4 views
10

J'ai deux littéraux d'objet:Fusionner deux littéraux objet en javascript

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

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

Besoin d'une fonction de fusion comme celui-ci:

dog = someMergingFunction(animal, dog); 

qui produit:

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

un de l'objet les littéraux doivent remplacer les propriétés identiques.

Comment faire ceci en Javascript?

+0

Dans votre exemple , comment 'someFunction' sait-il ce que' eat' garder, et lequel jeter? – Emmett

+0

peut-être que le premier serait le littéral d'objet primordial. lorsque vous fusionnez deux objets, vous devez gagner l'autre – ajsie

+1

@Emmett Une option consisterait à supposer que le second paramètre passé est prioritaire sur le premier. – Alex

Répondre

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

Ce qui suit devrait fonctionner:

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 les deux objets ont la même propriété, la valeur obj2 est prioritaire.

3

On suppose propriétés du premier paramètre remplacera les propriétés du 2ème paramètre (comme votre exemple), cela va faire:

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

Cela pourrait être Ecraser une mouche avec un buick, mais vous pouvez être intéressé de voir comment Dojo fait essentiellement la même chose dans dojo.mixin (au moins si j'ai bien compris la question).

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

La fonctionnalité de base est en dojo._mixin, tout dojo.mixin fait fonctionner itérativement pour plusieurs objets progressivement en un seul coup.

Notez que dojo.mixin fonctionne dans la direction opposée à ce que vous avez suggéré dans votre exemple.

3

Je recommande d'utiliser underscore.js car il contient des fonctionnalités pour cela et une charge de choses liées:

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

http://underscorejs.org/#extend

6

Je recommande fortement la méthode extend de jQuery, car il fournira un support de navigateur complet.

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

Rappelez-vous que le premier argument est la cible. Le bon point sur l'utilisation de Extend est que par le code ci-dessous, vous pouvez le faire prolonger récursive:

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

Voir la documentation du jQuery pour plus d'informations: jQuery Docs for Extend method

0

Il y a quelques bonnes suggestions ici. Je sais que c'est une question vraiment ancienne, mais pour les futurs visiteurs qui cherchent une solution légèrement plus flexible, j'ai une fonction similaire que j'ai écrit qui accepte un nombre d'objets dans un tableau et les fusionne tous ensemble et renvoie un seul objet avec les propriétés de tous les littéraux d'objet dans le tableau.

Remarque: l'ordre de priorité est déterminé par le tableau. Chaque objet suivant écrase les propriétés identiques si elles existent dans les objets précédents. Sinon, les nouvelles propriétés sont simplement ajoutées à l'objet unique renvoyé.

J'espère que cela aidera les futurs visiteurs à cette question. Voici la fonction, très court et doux:

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

Vous pouvez l'utiliser comme ceci:

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