web-dev-qa-db-fra.com

Comment fusionner deux objets javascript dans ES6 +?

J'en ai marre de devoir toujours écrire du code comme celui-ci:

function shallowExtend(obj1,obj2){
  var key;
  for ( key in obj2 ) {
    if ( obj2.hasOwnProperty(key) === false )  continue;
    obj1[key] = obj2[key]
  }
}

Ou si je ne veux pas écrire le code moi-même, implémentez une bibliothèque qui le fait déjà. ES6 + va sûrement venir à la rescousse pour nous fournir quelque chose comme un Object.prototype.extend(obj2...) ou Object.extend(obj1,obj2...)

Alors, ES6 + fournit-il une telle fonctionnalité? Si ce n'est déjà fait, une telle fonctionnalité est-elle prévue? Si ce n'est pas prévu, alors pourquoi pas?

132
balupton

Vous pourrez effectuer une fusion/extension/attribution peu profonde dans ES6 à l'aide de Object.assign:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

Syntaxe:

Object.assign ( target, sources);

... sources représente le ou les objets source.

Exemple:

var obj1 = {name: 'Daisy', age: 30};
var obj2 = {name: 'Casey'};

Object.assign(obj1, obj2);

console.log(obj1.name === 'Casey' && obj1.age === 30);
// true
197
Jack

Vous pouvez utiliser le syntaxe de propagation d'objet pour cela:

const merged = {...obj1, ...obj2}

Pour les tableaux, l'opérateur de diffusion faisait déjà partie de ES6 (ES2015), mais pour les objets, il était ajouté à la spécification de langue de l'ES9 (ES2018). Sa proposition a été activée par défaut dans des outils tels que Babel bien avant cela.

143
Thijs Koerselman

Je sais que c’est un peu un vieux problème, mais la solution la plus simple dans ES2015/ES6 est en fait assez simple, en utilisant Object.assign (),

Espérons que cela aide, cela fait DEEP fusionner également:

/**
 * Simple is object check.
 * @param item
 * @returns {boolean}
 */
export function isObject(item) {
  return (item && typeof item === 'object' && !Array.isArray(item) && item !== null);
}

/**
 * Deep merge two objects.
 * @param target
 * @param source
 */
export function mergeDeep(target, source) {
  if (isObject(target) && isObject(source)) {
    for (const key in source) {
      if (isObject(source[key])) {
        if (!target[key]) Object.assign(target, { [key]: {} });
        mergeDeep(target[key], source[key]);
      } else {
        Object.assign(target, { [key]: source[key] });
      }
    }
  }
  return target;
}

Exemple d'utilisation:

mergeDeep(this, { a: { b: { c: 123 } } });
// or
const merged = mergeDeep({a: 1}, { b : { c: { d: { e: 12345}}}});  
console.dir(merged); // { a: 1, b: { c: { d: [Object] } } }
11
Salakar

L'addition de Object.mixin _ est actuellement en discussion pour prendre en charge le comportement que vous demandez. https://mail.mozilla.org/pipermail/es-discuss/2012-December/027037.html

Bien que cela ne soit pas encore dans le brouillon ES6, il semble y avoir beaucoup de soutien, donc je pense que cela sera bientôt visible dans les brouillons.

7
Nathan Wall

ES6

Object.assign(o1,o2) ; 
Object.assign({},o1,o2) ; //safe inheritance
var copy=Object.assign({},o1); // clone o1
//------Transform array of objects to one object---
var subjects_assess=[{maths:92},{phy:75},{sport:99}];
Object.assign(...subjects_assess); // {maths:92,phy:75,sport:99}

ES7 ou Babel

{...o1,...o2} // inheritance
 var copy= {...o1};
6
Abdennour TOUMI

Peut-être le ES5 Object.defineProperties méthode fera le travail?

par exemple.

var a = {name:'fred'};
var b = {age: {value: 37, writeable: true}};

Object.defineProperties(a, b);

alert(a.age); // 37

Documentation MDN: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperties

5
RobG