# Immutabilité

# Les primitives sont immutables

const str = 'Hello world!'
const newStr = str.replace('world', 'Elodie')

str // 'Hello world!'

newStr // 'Hello Elodie!'

Aucune méthode invoquée sur une valeur primitive ne peut changer cette valeur

# Les objets sont mutables

Même s'ils sont déclarées avec const !

const obj = {} // Déclaration d'une variable contenant un objet vide

obj.prop = 'value' // Ajout d'une propriété 'prop' avec pour valeur 'value'

obj // { prop: 'value' }

# Call by sharing

Attention, en JavaScript, les arguments sont passés par une stratégie appelée "Call by Sharing" aux fonctions : c'est bien la même valeur qui est passée à la fonction.

Par conséquent, si on passe un argument mutable (autrement dit un objet) à une fonction, il est possible de modifier cet objet à l'intérieur de la fonction et cette modification sera visible à l'extérieur, après l'appel à la fonction.

Ceci modifie l'objet passé en argument (c'est mal) :

function addProp (obj, value) {
   obj.prop = value
}

const foo = {}

addProp(foo, 'Elodie')
foo // {prop: 'Elodie'}

En fonction pure :

function addProp (obj, value) {
   const newObj = obj // newObj aura la même valeur que obj ! Toute modification sur newObj sera faite sur la valeur de obj aussi !
   const realNewObj = Object.assign({}, obj, {prop: value})
   return realNewObj
}

Avec la syntaxe de décomposition (opens new window) (spread syntax (opens new window)):

function addProp (obj, value) {
   const newObj = obj // newObj aura la même valeur que obj ! Toute modification sur newObj sera faite sur la valeur de obj aussi !
   const realNewObj = {
     ...obj,
     prop: value
   }

   return realNewObj
}

Qui s’utilisera de cette façon :

const foo = {}

const bar = addProp(foo, 'valeur')

foo // {}
bar // {prop: 'valeur'}