2017-07-14 1 views
0

Disons que nous avons un objet comme:Quelle est la meilleure façon de mettre à jour certaines propriétés d'un objet de manière immuable en JavaScript?

const obj = { 
    foo: { 
    a: { type: 'foo', baz: 1 }, 
    b: { type: 'bar', baz: 2 }, 
    c: { type: 'foo', baz: 3 } 
    } 
} 

Maintenant, je veux mettre à jour toutes les propriétés baz-5 si le type de la propriété dans foo est foo. Et je voudrais le modifier de façon immuable, c'est-à-dire qu'il ne modifierait pas l'objet origine mais retournerait un nouvel objet.

+1

Vous voulez dire que vous voulez faire une nouvelle '{type: « foo »: baz: 5}' objet, ou si vous voulez un ensemble Nouvel objet 'obj'? – Barmar

+0

vous pourriez copier en profondeur 'obj' puis apporter les modifications à la copie –

+0

Oui, @JaromandaX! Mais une copie en profondeur (comme '_.deepClone') pourrait avoir un problème de performance si l'objet était un gros objet. Y a-t-il une idée sans copie profonde? –

Répondre

0

Object.assign est parfait pour cela, de la docs:

La méthode Object.assign() est utilisée pour copier les valeurs de toutes les propriétés propres dénombrables d'un ou plusieurs objets source à un objet cible. Cela renverra l'objet cible.

Et vous pouvez l'utiliser comme ceci:

Object.assign(
    {}, 
    obj, 
    { 
     foo: { 
      a: { 
       baz: obj.foo.a.type === 'foo' ? 5 : obj.foo.a 
      } 
     } 
    } 
); 
-1

Vous pouvez utiliser Object.entries(), Array.prototype.map(), élément propagation, propriété calculée, Object.assign()

const obj = { 
 
    foo: { 
 
    a: { type: 'foo', baz: 1 }, 
 
    b: { type: 'bar', baz: 2 }, 
 
    c: { type: 'foo', baz: 3 } 
 
    } 
 
} 
 

 
let key = Object.keys(obj).pop(); 
 

 
let res = {[key]: Object.assign({}, 
 
      ...Object.entries(obj[key]) 
 
      .map(([prop, {type,baz}]) => 
 
      ({[prop]: {type,baz:type === "foo" ? 5 : baz}}) 
 
     ))}; 
 
    
 
console.log(res, obj);

1

I normalement écrire Object.create() pour copie superficielle, mais une copie profonde (objet imbriqué) que je fais avec JSON.parse(JSON.stringify(nestedObject))

const obj = { 
    foo: { 
    a: { type: 'foo', baz: 1 }, 
    b: { type: 'bar', baz: 2 }, 
    c: { type: 'foo', baz: 3 } 
    } 
} 
var temp = JSON.parse(JSON.stringify(obj)) 

for(var i in temp.foo) { 
    if(temp.foo[i].type == "foo") { 
    temp.foo[i].baz = 5; 
    } 
} 
console.log(temp); 
console.log(obj); 
+1

Notez que votre méthode ne fonctionne que si toutes les valeurs sont des valeurs JSON valides ... les exceptions étant des dates, des fonctions, des nœuds DOM, etc. –