web-dev-qa-db-fra.com

Object.assign — substitue la propriété imbriquée

J'ai un objet a comme celui-ci:

const a = {
  user: {
   …
   groups: […]
   …
  }
}

moyennant quoi il y a beaucoup plus de propriétés dans a.user

Et je voudrais changer uniquement la valeur a.user.groups. Si je fais ça:

const b = Object.assign({}, a, {
  user: {
    groups: {}
  }
});

b n'a pas d'autre propriété que b.user.groups, tous les autres sont supprimés. Existe-t-il un moyen ES6 de modifier uniquement la propriété imbriquée sans perdre tous les autres, avec Object.assign?

28
philipp

Après quelques essais, je pouvais trouver une solution qui ressemble bien à Nice:

const b = Object.assign({}, a, {
  user: {
    ...a.user,
    groups: 'some changed value'
  }
});

Pour rendre cette réponse plus complète, voici une petite note:

const b = Object.assign({}, a)

est essentiellement le même que:

const b = { ...a }

puisqu'il ne fait que copier toutes les propriétés de a (...a) dans un nouvel objet. Donc, ce qui précède peut être écrit comme:

 const b = {
   ...a,          //copy everything from a
   user: {        //override the user property
      ...a.user,  //same sane: copy the everything from a.user
      groups: 'some changes value'  //override a.user.group
   }
 }
58
philipp

Vous pouvez le changer de cette façon,

const b = Object.assign({}, a, {
  user: Object.assign({}, a.user, {
          groups: {}
        })
});

ou juste faire,

const b = Object.assign({}, a);
b.user.groups = {};
6
pratZ

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 retournera l'objet cible.

assign method créera un nouvel objet en copiant de l'objet source, le problème. Si vous modifiez une méthode ultérieurement dans l'objet source, elle ne sera pas répercutée sur le nouvel objet. 

Utilisez create ()

La méthode Object.create () crée un nouvel objet avec l'objet prototype et les propriétés spécifiés.

const b = Object.create(a)
b.user.groups = {}
// if you don't want the prototype link add this
// b.prototype = Object.prototype 

De cette façon, vous avez un lien vers un via le prototype et si vous apportez des modifications à a, cela sera reflété dans b, et tout changement dans b n'affectera pas

4
Abdullah Alsigar

Vous avez demandé spécifiquement une méthode ES6 avec Object.assign, mais peut-être que quelqu'un d'autre préférera ma réponse plus générale: vous pouvez le faire facilement avec lodash, et personnellement, je pense que cette solution est plus lisible.

import * as _ from 'lodash';
_.set(a, 'user.groups', newGroupsValue);

Il mute l'objet.

3
Patryk Wlaź

Première petite réponse de phillips.

const object1 = {
  abc: {
    a: 1
  }
};

const object2 = {
  abc: {
    b: 2
  }
};

Object.assign(object1, {
    abc: {
        ...object1.abc,
        ...object2.abc
    }
});

console.log(object1);
// Object { abc: Object { a: 1, b: 2 } }
0
Ballpin