Comment fusionner dynamiquement les propriétés de deux objets JavaScript?
je dois pouvoir fusionner deux objets JavaScript (très simples) à 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 aurait-il un script pour cette ou connaissez un construit dans la façon de le faire? Je n'ai pas besoin de récursion, et je n'ai pas besoin de fusionner des fonctions, juste des méthodes sur des objets plats.
30 réponses
ECMAScript 2018 Standard Method
Vous devez utiliser objets répartis :
let merged = {...obj1, ...obj2};
/** There's no limit to the number of objects you can merge.
* Later properties overwrite earlier properties with the same name. */
const allRules = {...obj1, ...obj2, ...obj3};
ECMAScript 2015 (ES6) standard Method
/* For the case in question, you would do: */
Object.assign(obj1, obj2);
/** There's no limit to the number of objects you can merge.
* All objects get merged into the first object.
* Only the object in the first argument is mutated and returned.
* Later properties overwrite earlier properties with the same name. */
const allRules = Object.assign({}, obj1, obj2, obj3, etc);
(voir référence JavaScript MDN )
méthode pour ES5 et avant
for (var attrname in obj2) { obj1[attrname] = obj2[attrname]; }
notez que cela ajoutera simplement tous les attributs de obj2
à obj1
qui pourraient ne pas être ce que vous voulez si vous voulez toujours utiliser le obj1
non modifié .
si vous utilisez un cadre qui enveloppe tous vos prototypes , alors vous devez obtenir plus de fantaisie avec des vérifications comme hasOwnProperty
, mais ce code fonctionnera pour 99% des cas.
exemple de fonction:
/**
* Overwrites obj1's values with obj2's and adds obj2's if non existent in obj1
* @param obj1
* @param obj2
* @returns obj3 a new object based on obj1 and obj2
*/
function merge_options(obj1,obj2){
var obj3 = {};
for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; }
for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; }
return obj3;
}
jQuery a également une utilité pour cela: http://api.jquery.com/jQuery.extend / .
tiré de la documentation de jQuery:
// Merge options object into settings object
var settings = { validate: false, limit: 5, name: "foo" };
var options = { validate: true, name: "bar" };
jQuery.extend(settings, options);
// Now the content of settings object is the following:
// { validate: true, limit: 5, name: "bar" }
le code ci-dessus mutera le objet existant nommé settings
.
si vous voulez créer un nouvel objet sans modifier l'un ou l'autre des arguments, utilisez ceci:
var defaults = { validate: false, limit: 5, name: "foo" };
var options = { validate: true, name: "bar" };
/* Merge defaults and options, without modifying defaults */
var settings = $.extend({}, defaults, options);
// The content of settings variable is now the following:
// {validate: true, limit: 5, name: "bar"}
// The 'defaults' and 'options' variables remained the same.
le Harmony ECMAScript 2015 (ES6) précise Object.assign
ce qui va le faire.
Object.assign(obj1, obj2);
le soutien de navigateur actuel est obtenir mieux , mais si vous développez pour les navigateurs qui n'ont pas de soutien, vous pouvez utiliser un polyfill .
j'ai cherché sur Google le code pour fusionner les propriétés des objets et j'ai fini ici. Mais 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, espérons que quelqu'un d'autre le trouvera aussi utile.
(maintenant le code n'utilise pas Object.prototype
:)
Code
/*
* Recursively merge properties of two objects
*/
function MergeRecursive(obj1, obj2) {
for (var p in obj2) {
try {
// Property in destination object set; update its value.
if ( obj2[p].constructor==Object ) {
obj1[p] = MergeRecursive(obj1[p], obj2[p]);
} else {
obj1[p] = obj2[p];
}
} catch(e) {
// Property in destination object not set; create it and set its value.
obj1[p] = obj2[p];
}
}
return obj1;
}
un exemple
o1 = { a : 1,
b : 2,
c : {
ca : 1,
cb : 2,
cc : {
cca : 100,
ccb : 200 } } };
o2 = { a : 10,
c : {
ca : 10,
cb : 20,
cc : {
cca : 101,
ccb : 202 } } };
o3 = MergeRecursive(o1, o2);
produit un objet o3 comme
o3 = { a : 10,
b : 2,
c : {
ca : 10,
cb : 20,
cc : {
cca : 101,
ccb : 202 } } };
Note que underscore.js
's extend
-méthode est-ce dans un one-liner:
_.extend({name : 'moe'}, {age : 50});
=> {name : 'moe', age : 50}
similaire à jQuery extend (), vous avez la même fonction dans AngularJS :
// Merge the 'options' object into the 'settings' object
var settings = {validate: false, limit: 5, name: "foo"};
var options = {validate: true, name: "bar"};
angular.extend(settings, options);
j'ai besoin de fusionner des objets d'aujourd'hui, et cette question (et réponses) m'a beaucoup aidé. J'ai essayé certaines des réponses, mais aucune d'elles ne correspond à mes besoins, donc j'ai combiné certaines des réponses, ajouté quelque chose moi-même et est venu avec une nouvelle fonction de fusion. Le voici:
var merge = function() {
var obj = {},
i = 0,
il = arguments.length,
key;
for (; i < il; i++) {
for (key in arguments[i]) {
if (arguments[i].hasOwnProperty(key)) {
obj[key] = arguments[i][key];
}
}
}
return obj;
};
quelques exemples d'usages:
var t1 = {
key1: 1,
key2: "test",
key3: [5, 2, 76, 21]
};
var t2 = {
key1: {
ik1: "hello",
ik2: "world",
ik3: 3
}
};
var t3 = {
key2: 3,
key3: {
t1: 1,
t2: 2,
t3: {
a1: 1,
a2: 3,
a4: [21, 3, 42, "asd"]
}
}
};
console.log(merge(t1, t2));
console.log(merge(t1, t3));
console.log(merge(t2, t3));
console.log(merge(t1, t2, t3));
console.log(merge({}, t1, { key1: 1 }));
vous pouvez utiliser object spread properties - actuellement une proposition ECMAScript de stade 3.
const obj1 = { food: 'pizza', car: 'ford' };
const obj2 = { animal: 'dog' };
const obj3 = { ...obj1, ...obj2 };
console.log(obj3);
les solutions données doivent être modifiées pour vérifier source.hasOwnProperty(property)
dans les boucles for..in
avant d'attribuer - sinon, vous finissez par copier les propriétés de l'ensemble de la chaîne prototype, ce qui est rarement désiré...
fusionner les propriétés de N objets dans une ligne de code
une méthode Object.assign
fait partie de la norme ECMAScript 2015 (ES6) et fait exactement ce dont vous avez besoin. ( IE
non supporté)
var clone = Object.assign({}, obj);
L'Objet.assign() la méthode 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.
Le polyfill pour soutenir les anciens navigateurs:
if (!Object.assign) {
Object.defineProperty(Object, 'assign', {
enumerable: false,
configurable: true,
writable: true,
value: function(target) {
'use strict';
if (target === undefined || target === null) {
throw new TypeError('Cannot convert first argument to object');
}
var to = Object(target);
for (var i = 1; i < arguments.length; i++) {
var nextSource = arguments[i];
if (nextSource === undefined || nextSource === null) {
continue;
}
nextSource = Object(nextSource);
var keysArray = Object.keys(nextSource);
for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
var nextKey = keysArray[nextIndex];
var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
if (desc !== undefined && desc.enumerable) {
to[nextKey] = nextSource[nextKey];
}
}
}
return to;
}
});
}
les deux suivants sont probablement un bon point de départ. lodash a également une fonction customizer pour ces besoins spéciaux!
_.extend
( http://underscorejs.org/#extend )
_.merge
( https://lodash.com/docs#merge )
au fait, ce que vous faites, c'est écraser les propriétés, pas fusionner...
Voici comment JavaScript objects area a réellement fusionné: seules les clés de l'objet to
qui ne sont pas des objets eux-mêmes seront écrasées par from
. Tout le reste sera réellement fusionné . Bien sûr, vous pouvez modifier ce comportement pour ne pas écraser tout ce qui existe comme si to[n] is undefined
, etc...:
var realMerge = function (to, from) {
for (n in from) {
if (typeof to[n] != 'object') {
to[n] = from[n];
} else if (typeof from[n] == 'object') {
to[n] = realMerge(to[n], from[n]);
}
}
return to;
};
Utilisation:
var merged = realMerge(obj1, obj2);
Voici mon coup de poignard qui
- supporte la fusion profonde
- ne mute pas les arguments
- prend un nombre quelconque d'arguments
- N'étend pas l'objet prototype
- Ne dépend pas d'une autre bibliothèque ( jQuery , MooTools , trait de Soulignement.js , etc.)
- comprend le contrôle hasOwnProperty
-
Est court :)
/* Recursively merge properties and return new object obj1 <- obj2 [ <- ... ] */ function merge () { var dst = {} ,src ,p ,args = [].splice.call(arguments, 0) ; while (args.length > 0) { src = args.splice(0, 1)[0]; if (toString.call(src) == '[object Object]') { for (p in src) { if (src.hasOwnProperty(p)) { if (toString.call(src[p]) == '[object Object]') { dst[p] = merge(dst[p] || {}, src[p]); } else { dst[p] = src[p]; } } } } } return dst; }
exemple:
a = {
"p1": "p1a",
"p2": [
"a",
"b",
"c"
],
"p3": true,
"p5": null,
"p6": {
"p61": "p61a",
"p62": "p62a",
"p63": [
"aa",
"bb",
"cc"
],
"p64": {
"p641": "p641a"
}
}
};
b = {
"p1": "p1b",
"p2": [
"d",
"e",
"f"
],
"p3": false,
"p4": true,
"p6": {
"p61": "p61b",
"p64": {
"p642": "p642b"
}
}
};
c = {
"p1": "p1c",
"p3": null,
"p6": {
"p62": "p62c",
"p64": {
"p643": "p641c"
}
}
};
d = merge(a, b, c);
/*
d = {
"p1": "p1c",
"p2": [
"d",
"e",
"f"
],
"p3": null,
"p5": null,
"p6": {
"p61": "p61b",
"p62": "p62c",
"p63": [
"aa",
"bb",
"cc"
],
"p64": {
"p641": "p641a",
"p642": "p642b",
"p643": "p641c"
}
},
"p4": true
};
*/
objet.attribuer()
ECMAScript 2015 (ES6)
il s'agit d'une nouvelle technologie, faisant partie de la norme ECMAScript 2015 (ES6). Les spécifications de cette technologie ont été finalisées, mais vérifiez la table de compatibilité pour l'utilisation et l'état de mise en œuvre dans divers navigateurs.
L'Objet.assignez () la méthode est utilisée pour copier les valeurs de toutes les propriétés propres énumérables d'un ou plus d'objets source vers un objet cible. Il sera de retour de l'objet cible.
var o1 = { a: 1 };
var o2 = { b: 2 };
var o3 = { c: 3 };
var obj = Object.assign(o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
console.log(o1); // { a: 1, b: 2, c: 3 }, target object itself is changed.
Pour ne pas-trop-compliqué objets, vous pourriez utiliser JSON :
var obj1 = { food: 'pizza', car: 'ford' }
var obj2 = { animal: 'dog', car: 'chevy'}
var objMerge;
objMerge = JSON.stringify(obj1) + JSON.stringify(obj2);
// {"food": "pizza","car":"ford"}{"animal":"dog","car":"chevy"}
objMerge = objMerge.replace(/\}\{/, ","); // \_ replace with comma for valid JSON
objMerge = JSON.parse(objMerge); // { food: 'pizza', animal: 'dog', car: 'chevy'}
// Of same keys in both objects, the last object's value is retained_/
rappelez-vous que dans cet exemple "}{" ne doit pas se produire dans une chaîne!
la meilleure façon pour vous de faire ceci est d'ajouter une propriété correcte qui est non-énumérable en utilisant L'objet.defineProperty.
de cette façon, vous serez encore en mesure d'itérer sur vos propriétés d'objets sans avoir le" extend " nouvellement créé que vous obtiendriez si vous deviez créer la propriété avec Objet.prototype.étendre.
Espérons que cela aide:
Object.defineProperty(Object.prototype, "extend", { enumerable: false, value: function(from) { var props = Object.getOwnPropertyNames(from); var dest = this; props.forEach(function(name) { if (name in dest) { var destination = Object.getOwnPropertyDescriptor(from, name); Object.defineProperty(dest, name, destination); } }); return this; } });
une fois que vous avez ce travail, vous pouvez faire:
var obj = { name: 'stack', finish: 'overflow' } var replacement = { name: 'stock' }; obj.extend(replacement);
je viens d'écrire un billet de blog à ce sujet ici: http://onemoredigit.com/post/1527191998/extending-objects-in-node-js
vous pouvez simplement utiliser jQuery extend
var obj1 = { val1: false, limit: 5, name: "foo" };
var obj2 = { val2: true, name: "bar" };
jQuery.extend(obj1, obj2);
Maintenant obj1
contient toutes les valeurs de obj1
et obj2
il y a une bibliothèque appelée deepmerge
sur GitHub : cela semble obtenir une certaine traction. Il s'agit d'une application autonome, disponible par l'intermédiaire des gestionnaires de paquets npm et bower.
je serais enclin à utiliser ou à améliorer ce code au lieu de copier-coller des réponses.
Juste, si quelqu'un est à l'aide de Google Fermeture de la Bibliothèque :
goog.require('goog.object');
var a = {'a': 1, 'b': 2};
var b = {'b': 3, 'c': 4};
goog.object.extend(a, b);
// Now object a == {'a': 1, 'b': 3, 'c': 4};
fonction d'aide similaire existe pour le tableau :
var a = [1, 2];
var b = [3, 4];
goog.array.extend(a, b); // Extends array 'a'
goog.array.concat(a, b); // Returns concatenation of array 'a' and 'b'
j'ai étendu la méthode de David Coallier:
- ajouté la possibilité de fusionner plusieurs objets
- supporte des objets profonds
- paramètre override (qui est détecté si le dernier paramètre est un booléen)
si override est false, aucune propriété n'est annulée mais de nouvelles propriétés seront ajoutées.
Usage: obj.de fusion(fusion... [, outrepasser]);
Voici mon code:
Object.defineProperty(Object.prototype, "merge", {
enumerable: false,
value: function () {
var override = true,
dest = this,
len = arguments.length,
props, merge, i, from;
if (typeof(arguments[arguments.length - 1]) === "boolean") {
override = arguments[arguments.length - 1];
len = arguments.length - 1;
}
for (i = 0; i < len; i++) {
from = arguments[i];
if (from != null) {
Object.getOwnPropertyNames(from).forEach(function (name) {
var descriptor;
// nesting
if ((typeof(dest[name]) === "object" || typeof(dest[name]) === "undefined")
&& typeof(from[name]) === "object") {
// ensure proper types (Array rsp Object)
if (typeof(dest[name]) === "undefined") {
dest[name] = Array.isArray(from[name]) ? [] : {};
}
if (override) {
if (!Array.isArray(dest[name]) && Array.isArray(from[name])) {
dest[name] = [];
}
else if (Array.isArray(dest[name]) && !Array.isArray(from[name])) {
dest[name] = {};
}
}
dest[name].merge(from[name], override);
}
// flat properties
else if ((name in dest && override) || !(name in dest)) {
descriptor = Object.getOwnPropertyDescriptor(from, name);
if (descriptor.configurable) {
Object.defineProperty(dest, name, descriptor);
}
}
});
}
}
return this;
}
});
des Exemples et des cas de tests:
function clone (obj) {
return JSON.parse(JSON.stringify(obj));
}
var obj = {
name : "trick",
value : "value"
};
var mergeObj = {
name : "truck",
value2 : "value2"
};
var mergeObj2 = {
name : "track",
value : "mergeObj2",
value2 : "value2-mergeObj2",
value3 : "value3"
};
assertTrue("Standard", clone(obj).merge(mergeObj).equals({
name : "truck",
value : "value",
value2 : "value2"
}));
assertTrue("Standard no Override", clone(obj).merge(mergeObj, false).equals({
name : "trick",
value : "value",
value2 : "value2"
}));
assertTrue("Multiple", clone(obj).merge(mergeObj, mergeObj2).equals({
name : "track",
value : "mergeObj2",
value2 : "value2-mergeObj2",
value3 : "value3"
}));
assertTrue("Multiple no Override", clone(obj).merge(mergeObj, mergeObj2, false).equals({
name : "trick",
value : "value",
value2 : "value2",
value3 : "value3"
}));
var deep = {
first : {
name : "trick",
val : "value"
},
second : {
foo : "bar"
}
};
var deepMerge = {
first : {
name : "track",
anotherVal : "wohoo"
},
second : {
foo : "baz",
bar : "bam"
},
v : "on first layer"
};
assertTrue("Deep merges", clone(deep).merge(deepMerge).equals({
first : {
name : "track",
val : "value",
anotherVal : "wohoo"
},
second : {
foo : "baz",
bar : "bam"
},
v : "on first layer"
}));
assertTrue("Deep merges no override", clone(deep).merge(deepMerge, false).equals({
first : {
name : "trick",
val : "value",
anotherVal : "wohoo"
},
second : {
foo : "bar",
bar : "bam"
},
v : "on first layer"
}));
var obj1 = {a: 1, b: "hello"};
obj1.merge({c: 3});
assertTrue(obj1.equals({a: 1, b: "hello", c: 3}));
obj1.merge({a: 2, b: "mom", d: "new property"}, false);
assertTrue(obj1.equals({a: 1, b: "hello", c: 3, d: "new property"}));
var obj2 = {};
obj2.merge({a: 1}, {b: 2}, {a: 3});
assertTrue(obj2.equals({a: 3, b: 2}));
var a = [];
var b = [1, [2, 3], 4];
a.merge(b);
assertEquals(1, a[0]);
assertEquals([2, 3], a[1]);
assertEquals(4, a[2]);
var o1 = {};
var o2 = {a: 1, b: {c: 2}};
var o3 = {d: 3};
o1.merge(o2, o3);
assertTrue(o1.equals({a: 1, b: {c: 2}, d: 3}));
o1.b.c = 99;
assertTrue(o2.equals({a: 1, b: {c: 2}}));
// checking types with arrays and objects
var bo;
a = [];
bo = [1, {0:2, 1:3}, 4];
b = [1, [2, 3], 4];
a.merge(b);
assertTrue("Array stays Array?", Array.isArray(a[1]));
a = [];
a.merge(bo);
assertTrue("Object stays Object?", !Array.isArray(a[1]));
a = [];
a.merge(b);
a.merge(bo);
assertTrue("Object overrides Array", !Array.isArray(a[1]));
a = [];
a.merge(b);
a.merge(bo, false);
assertTrue("Object does not override Array", Array.isArray(a[1]));
a = [];
a.merge(bo);
a.merge(b);
assertTrue("Array overrides Object", Array.isArray(a[1]));
a = [];
a.merge(bo);
a.merge(b, false);
assertTrue("Array does not override Object", !Array.isArray(a[1]));
la méthode mes égaux peut être trouvée ici: comparaison D'objet en JavaScript
dans MooTools , il y a objet.merge () :
Object.merge(obj1, obj2);
la fusion d'objets est simple.
var obj1 = { food: 'pizza', car: 'ford' }
var obj2 = { animal: 'dog', car: 'BMW' }
var obj3 = {a: "A"}
var mergedObj = Object.assign(obj1,obj2,obj3)
console.log(mergedObj);
les objets sont fusionnés de droite à gauche, ce qui signifie que les objets ayant des propriétés identiques à celles des objets à leur droite seront remplacés.
dans cet exemple, obj2.car
l'emporte sur obj1.car
Dans Ext JS 4, il peut être fait comme suit:
var mergedObject = Ext.Object.merge(object1, object2)
// Or shorter:
var mergedObject2 = Ext.merge(object1, object2)
voir Fusion( objet ) : Objet .
Avec Souligné.js , pour fusionner un tableau d'objets faire:
var arrayOfObjects = [ {a:1}, {b:2, c:3}, {d:4} ];
_(arrayOfObjects).reduce(function(memo, o) { return _(memo).extend(o); });
il en résulte:
Object {a: 1, b: 2, c: 3, d: 4}
Basé sur Markus' et vsync " réponse , c'est une version élargie. La fonction prend n'importe quel nombre d'arguments. Il peut être utilisé pour définir les propriétés sur les noeuds DOM et fait des copies profondes des valeurs. Toutefois, le premier argument est donnée par référence.
pour détecter un nœud DOM, la fonction isDOMNode() est utilisée (voir la question sur le débordement de la pile isDOM JavaScript-Comment faire vous vérifiez 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
function mergeRecursive() {
// _mergeRecursive does the actual job with two arguments.
var _mergeRecursive = function (dst, src) {
if (isDOMNode(src) || typeof src !== 'object' || src === null) {
return dst;
}
for (var p in src) {
if (!src.hasOwnProperty(p))
continue;
if (src[p] === undefined)
continue;
if ( typeof src[p] !== 'object' || src[p] === null) {
dst[p] = src[p];
} else if (typeof dst[p]!=='object' || dst[p] === null) {
dst[p] = _mergeRecursive(src[p].constructor===Array ? [] : {}, src[p]);
} else {
_mergeRecursive(dst[p], src[p]);
}
}
return dst;
}
// Loop through arguments and merge them into the first argument.
var out = arguments[0];
if (typeof out !== 'object' || out === null)
return out;
for (var i = 1, il = arguments.length; i < il; i++) {
_mergeRecursive(out, arguments[i]);
}
return out;
}
quelques exemples
Set innerHTML et le style d'un Élément HTML
mergeRecursive(
document.getElementById('mydiv'),
{style: {border: '5px solid green', color: 'red'}},
{innerHTML: 'Hello world!'});
fusionner des tableaux et des objets. Notez que l'indéfini peut être utilisé pour préserver les valeurs dans le tableau de gauche/objet.
o = mergeRecursive({a:'a'}, [1,2,3], [undefined, null, [30,31]], {a:undefined, b:'b'});
// o = {0:1, 1:null, 2:[30,31], a:'a', b:'b'}
tout argument n'étant pas un objet JavaScript (y compris null) sera ignoré. Sauf pour le premier argument, les noeuds DOM sont également rejetés. Attention: les chaînes créées comme new String() sont en fait des objets.
o = mergeRecursive({a:'a'}, 1, true, null, undefined, [1,2,3], 'bc', new String('de'));
// o = {0:'d', 1:'e', 2:3, a:'a'}
si vous voulez fusionner deux objets dans une nouvelle (sans affecter aucun des deux) fourniture {} comme premier argument
var a={}, b={b:'abc'}, c={c:'cde'}, o;
o = mergeRecursive(a, b, c);
// o===a is true, o===b is false, o===c is false
Modifier (par ReaperSoon):
Pour fusionner des tableaux
function mergeRecursive(obj1, obj2) {
if (Array.isArray(obj2)) { return obj1.concat(obj2); }
for (var p in obj2) {
try {
// Property in destination object set; update its value.
if ( obj2[p].constructor==Object ) {
obj1[p] = mergeRecursive(obj1[p], obj2[p]);
} else if (Array.isArray(obj2[p])) {
obj1[p] = obj1[p].concat(obj2[p]);
} else {
obj1[p] = obj2[p];
}
} catch(e) {
// Property in destination object not set; create it and set its value.
obj1[p] = obj2[p];
}
}
return obj1;
}
vous devez utiliser lodash defaultsDeep
_.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } });
// → { 'user': { 'name': 'barney', 'age': 36 } }
il est intéressant de mentionner que la version du 140byt.ES collection est la résolution de la tâche dans un minimum d'espace et vaut la peine d'un essai à cette fin:
Code:
function m(a,b,c){for(c in b)b.hasOwnProperty(c)&&((typeof a[c])[0]=='o'?m(a[c],b[c]):a[c]=b[c])}
l'Utilisation de votre but:
m(obj1,obj2);
voici le original Gist .
j'utilise ce qui suit qui est en JavaScript pur. Il part de l'argument le plus juste et les combine jusqu'au premier argument. Il n'y a pas de valeur de retour, seul le premier argument est modifié et le paramètre left-most (sauf le premier) a le plus de poids sur les propriétés.
var merge = function() {
var il = arguments.length;
for (var i = il - 1; i > 0; --i) {
for (var key in arguments[i]) {
if (arguments[i].hasOwnProperty(key)) {
arguments[0][key] = arguments[i][key];
}
}
}
};
Wow.. c'est le premier StackOverflow post que j'ai vu avec plusieurs pages. Toutes nos excuses pour avoir ajouté une autre "réponse "
cette méthode est pour ES5 & Earlier - Il ya beaucoup d'autres réponses traitant ES6.
Je n'ai vu aucun " deep " objet de fusion utilisant la arguments
propriété. Voici ma réponse - compact & recursive , permettant de passer des arguments d'objet illimités:
function extend() {
for (var o = {}, i = 0; i < arguments.length; i++) {
// if (arguments[i].constructor !== Object) continue;
for (var k in arguments[i]) {
if (arguments[i].hasOwnProperty(k)) {
o[k] = arguments[i][k].constructor === Object ? extend(o[k] || {}, arguments[i][k]) : arguments[i][k];
}
}
}
return o;
}
la partie commentée est facultative .. il sautera simplement les arguments passés qui ne sont pas des objets (empêchant les erreurs).
exemple:
extend({
api: 1,
params: {
query: 'hello'
}
}, {
params: {
query: 'there'
}
});
// outputs {api: 1, params: {query: 'there'}}
Cette réponse n'est qu'une goutte dans l'océan ...