J'ai besoin de pouvoir fusionner deux (très simples) objets JavaScript au moment de l'exécution. Par exemple, je voudrais:
var obj1 = { food: 'pizza', car: 'ford' }
var obj2 = { animal: 'dog' }
obj1.merge(obj2);
//obj1 now has three properties: food, car, and animal
Quelqu'un at-il un script pour cela ou connaît-il une manière intégrée de le faire? Je n'ai pas besoin de récursivité, et je n'ai pas besoin de fusionner de fonctions, juste des méthodes sur des objets plats.
javascript
javascript-objects
JC Grubbs
la source
la source
var obj2 = { animal: 'dog', food: 'bone' };
, la fusion serait{ food: 'bone', car: 'ford', animal: 'dog' }
. Si vous travaillez avec des "données imbriquées" et souhaitez une "fusion profonde", recherchez les réponses qui mentionnent "fusion profonde" ou "récursivité". Si vous avez des valeurs qui sontarrays
, alors utilisez l'option "arrayMerge" du github "TehShrike / deepmerge", comme mentionné ici .Réponses:
Méthode standard ECMAScript 2018
Vous utiliseriez la propagation d'objets :
merged
est maintenant l'union deobj1
etobj2
. Les propriétés deobj2
remplaceront celles deobj1
.Voici également la documentation MDN de cette syntaxe. Si vous utilisez babel, vous aurez besoin du plugin babel-plugin-transform-object-rest-spread pour que cela fonctionne.
ECMAScript 2015 (ES6) Méthode standard
(voir référence JavaScript MDN )
Méthode pour ES5 et versions antérieures
Notez que cela simplement ajouter tous les attributs de
obj2
àobj1
qui pourrait ne pas être ce que vous voulez si vous voulez continuer à utiliser la non modifiéeobj1
.Si vous utilisez un cadre qui craque partout dans vos prototypes, vous devez devenir plus amateur avec des vérifications comme
hasOwnProperty
, mais ce code fonctionnera dans 99% des cas.Exemple de fonction:
la source
var merged = {...obj1, ...obj2}
.{...obj1, ...{animal: 'dog'}}
jQuery a également un utilitaire pour cela: http://api.jquery.com/jQuery.extend/ .
Tiré de la documentation jQuery:
Le code ci-dessus mute l' objet existant nommé
settings
.Si vous souhaitez créer un nouvel objet sans modifier aucun des arguments, utilisez ceci:
la source
jQuery.extend(true,settings,override)
, ce qui est important si une propriété des paramètres contient un objet et que la substitution n'a qu'une partie de cet objet. Au lieu de supprimer les propriétés inégalées, le paramètre profond ne se mettra à jour que là où il existe. Le défaut est faux.Le Harmony ECMAScript 2015 (ES6) spécifie
Object.assign
qui le fera.La prise en charge actuelle des navigateurs s'améliore , mais si vous développez pour des navigateurs non pris en charge, vous pouvez utiliser un polyfill .
la source
Object.assign
a une couverture assez décente: kangax.github.io/compat-table/es6/…Object.assign({}, obj1, obj2)
J'ai recherché du code pour fusionner les propriétés des objets sur Google et je me suis retrouvé ici. Cependant, comme il n'y avait pas de code pour la fusion récursive, je l'ai écrit moi-même. (Peut-être que jQuery extend est récursif BTW?) Quoi qu'il en soit, j'espère que quelqu'un d'autre le trouvera également utile.
(Maintenant, le code n'utilise pas
Object.prototype
:)Code
Un exemple
Produit un objet o3 comme
la source
Notez que
underscore.js
laextend
méthode 's fait cela dans une seule ligne:la source
_({}).extend(obj1, obj2);
_.defaults(object, *defaults)
"Remplissez les propriétés nulles et non définies dans l'objet avec les valeurs des objets par défaut et renvoyez l'objet."var mergedObj = _.extend({}, obj1, obj2)
.Semblable à jQuery extend (), vous avez la même fonction dans AngularJS :
la source
J'ai besoin de fusionner des objets aujourd'hui, et cette question (et ses réponses) m'a beaucoup aidé. J'ai essayé certaines des réponses, mais aucune d'entre elles ne correspondait à mes besoins, j'ai donc combiné certaines des réponses, ajouté moi-même quelque chose et proposé une nouvelle fonction de fusion. C'est ici:
Quelques exemples d'utilisations:
la source
merge({}, t1, { key1: 1 })
?Vous pouvez utiliser les propriétés de répartition des objets - actuellement une proposition ECMAScript d'étape 3.
la source
Les solutions données doivent être modifiées pour archiver
source.hasOwnProperty(property)
lesfor..in
boucles avant d'affecter - sinon, vous finissez par copier les propriétés de l'ensemble de la chaîne de prototypes, ce qui est rarement souhaité ...la source
Fusionner les propriétés de N objets dans une seule ligne de code
Une
Object.assign
méthode fait partie de la norme ECMAScript 2015 (ES6) et fait exactement ce dont vous avez besoin. (IE
non pris en charge)Lire la suite...
Le polyfill pour supporter les anciens navigateurs:
la source
Objects.assign
renvoie un objet fusionné auquel les autres réponses ne répondent pas. C'est un style de programmation plus fonctionnel.Les deux suivants sont probablement un bon point de départ. lodash a également une fonction de personnalisation pour ces besoins spéciaux!
_.extend
( http://underscorejs.org/#extend )_.merge
( https://lodash.com/docs#merge )la source
Soit dit en passant, ce que vous faites, c'est écraser les propriétés, pas fusionner ...
C'est ainsi que la zone des objets JavaScript a vraiment fusionné: seules les clés de l'
to
objet qui ne sont pas des objets eux-mêmes seront écrasées parfrom
. Tout le reste sera vraiment fusionné . Bien sûr, vous pouvez modifier ce comportement pour ne pas écraser tout ce qui existe comme sito[n] is undefined
, etc ...:Usage:
la source
Voici mon coup de couteau qui
C'est court :)
Exemple:
la source
{}
comme premier paramètre ou que la fonction modifie l'objet d'origine. Par conséquent , si vous changezdst = {}
dedst = arguments[0]
cela va changer le premier objet que vous passez à l'objet fusionnétoString.call(src) == '[object Object]'
pour vérifier s'il y a un objet ou non.typeof src
c'est beaucoup mieux. De plus, il transforme les tableaux en objets (au moins, j'ai un tel comportement sur le dernier chrome).Object.assign ()
ECMAScript 2015 (ES6)
Il s'agit d'une nouvelle technologie, faisant partie de la norme ECMAScript 2015 (ES6). La spécification de cette technologie a été finalisée, mais vérifiez le tableau de compatibilité pour l'état d'utilisation et d'implémentation dans divers navigateurs.
La méthode Object.assign () est utilisée pour copier les valeurs de toutes les propriétés propres énumérables d'un ou plusieurs objets source vers un objet cible. Il renverra l'objet cible.
la source
Pour les objets pas trop compliqués, vous pouvez utiliser JSON :
Rappelez-vous que dans cet exemple, "} {" ne doit pas apparaître dans une chaîne!
la source
var so1 = JSON.stringify(obj1); var so2 = JSON.stringify(obj1); objMerge = so1.substr(0, so1.length-1)+","+so2.substr(1); console.info(objMerge);
function merge(obj1, obj2) { return JSON.parse((JSON.stringify(obj1) + JSON.stringify(obj2)) .replace(/\}\{/g, ',').replace(/,\}/g, '}').replace(/\{,/g, '{')); }
objMerge = JSON.parse((JSON.stringify(obj1) + JSON.stringify(obj2)).replace(/\}\{/, ", "));
Il y a une bibliothèque appelée
deepmerge
sur GitHub : Cela semble obtenir une certaine traction. Il s'agit d'un logiciel autonome, disponible via les gestionnaires de packages npm et bower.Je serais enclin à utiliser ou à améliorer cela au lieu de copier-coller le code des réponses.
la source
La meilleure façon de procéder consiste à ajouter une propriété appropriée non énumérable à l'aide d'Object.defineProperty.
De cette façon, vous pourrez toujours parcourir les propriétés de vos objets sans avoir la "nouvelle extension" que vous obtiendriez si vous deviez créer la propriété avec Object.prototype.extend.
Espérons que cela aide:
Une fois que cela fonctionne, vous pouvez faire:
Je viens d'écrire un article de blog à ce sujet ici: http://onemoredigit.com/post/1527191998/extending-objects-in-node-js
la source
Vous pouvez simplement utiliser jQuery
extend
obj1
Contient maintenant toutes les valeurs deobj1
etobj2
la source
jQuery.extend( target [, object1 ] [, objectN ] )
Le prototype a ceci:
obj1.extend(obj2)
fera ce que vous voulez.la source
Object.prototype
et nonObject
... Bonne idée ou non, c'est ce que fait leprototype.js
framework, et donc si vous l'utilisez ou un autre framework qui en dépend,Object.prototype
sera déjà étendu avecextend
.Object.prototype
?Object.extend
n'interfère pas avec vos objets, il attache simplement une fonction à unObject
objet. Etobj1.extend(obj2)
n'est pas la bonne façon de tirer la fonction, utilisezObject.extend(obj1, obj2)
insted** La fusion d'objets est simple à utiliser
Object.assign
ou à l'...
opérateur d' étalement **Les objets sont fusionnés de droite à gauche, cela signifie que les objets qui ont des propriétés identiques à celles des objets à droite seront remplacés.
Dans cet exemple,
obj2.car
remplaceobj1.car
la source
Juste si quelqu'un utilise Google Closure Library :
Une fonction d'assistance similaire existe pour le tableau :
la source
J'ai étendu la méthode de David Coallier:
Si la substitution est fausse, aucune propriété n'est remplacée mais de nouvelles propriétés seront ajoutées.
Utilisation: obj.merge (fusionne ... [, override]);
Voici mon code:
Exemples et cas de test:
Ma méthode d'égalité peut être trouvée ici: Comparaison d'objets en JavaScript
la source
Dans MooTools , il y a Object.merge () :
la source
Dans Ext JS 4, cela peut être fait comme suit:
Voir merge (object): Object .
la source
Wow .. c'est le premier article StackOverflow que j'ai vu avec plusieurs pages. Toutes mes excuses pour avoir ajouté une autre "réponse"
Cette méthode s'applique à ES5 et aux versions antérieures - il existe de nombreuses autres réponses concernant ES6.
Je n'ai vu aucun objet "profond" fusionner en utilisant la
arguments
propriété. Voici ma réponse - compacte et récursive , permettant de passer des arguments d'objet illimités:La partie commentée est facultative. Elle sautera simplement les arguments passés qui ne sont pas des objets (empêchant les erreurs).
Exemple:
la source
Utilisation de jQuery.extend () - Lien
Utilisation de _.merge () - Lien
Utilisation de _.extend () - Lien
Utilisation d'Object.assign () ECMAScript 2015 (ES6) - Lien
Sortie de tous
la source
Basé sur la réponse de Markus et vsync , il s'agit d'une version étendue. La fonction prend n'importe quel nombre d'arguments. Il peut être utilisé pour définir des propriétés sur les nœuds DOM et faire des copies complètes des valeurs. Cependant, le premier argument est donné par référence.
Pour détecter un nœud DOM, la fonction isDOMNode () est utilisée (voir la question Stack Overflow JavaScript isDOM - Comment vérifier si un objet JavaScript est un objet DOM? )
Il a été testé dans Opera 11, Firefox 6, Internet Explorer 8 et Google Chrome 16.
Code
Quelques exemples
Définir innerHTML et le style d'un élément HTML
Fusionner des tableaux et des objets. Notez que non défini peut être utilisé pour conserver les valeurs dans le tableau / objet de gauche.
Tout argument ne correspondant pas à un objet JavaScript (y compris null) sera ignoré. À l'exception du premier argument, les nœuds DOM sont également ignorés. Attention, c'est-à-dire que les chaînes, créées comme de nouvelles String () sont en fait des objets.
Si vous voulez fusionner deux objets dans un nouveau (sans affecter aucun des deux), fournissez {} comme premier argument
Modifier (par ReaperSoon):
Pour fusionner également des tableaux
la source
la source
Vous devez utiliser les valeurs par défaut de lodash
la source
Avec Underscore.js , pour fusionner un tableau d'objets, procédez comme suit:
Il en résulte:
la source