{"id":841,"date":"2018-06-28T07:11:00","date_gmt":"2018-06-28T05:11:00","guid":{"rendered":"https:\/\/alistapart.com\/it\/article\/perche-la-mutazione-fa-paura\/"},"modified":"2018-06-28T07:11:00","modified_gmt":"2018-06-28T05:11:00","slug":"perche-la-mutazione-fa-paura","status":"publish","type":"article","link":"https:\/\/alistapart.com\/it\/article\/perche-la-mutazione-fa-paura\/","title":{"rendered":"Perch\u00e9 la mutazione fa paura"},"content":{"rendered":"<div class=\"main-content pre-article\">\n<p class=\"editors-note\"><b>Nota degli editori:<\/b> Questo articolo contiene delle lezioni esempio tratte da <a href=\"https:\/\/learnjavascript.today\/\">Learn JavaScript<\/a>, un corso che vi aiuta a imparare JavaScript per realizzare da zero dei component per il mondo reale.<\/p>\n<\/div>\n<p><i>Mutare<\/i> significa cambiare forma o natura. Qualcosa che \u00e8 mutabile pu\u00f2 essere cambiato mentre qualcosa che \u00e8 immutabile non pu\u00f2 cambiare. Per comprendere la mutazione, pensate agli X-Men. In X-Men, le persone possono improvvisamente assumere dei poteri. Il problema \u00e8 che non sapete quando emergeranno questi poteri. Immaginatevi il vostro amico che diventa blu e che tutto a un tratto ha la pelliccia: pu\u00f2 essere spaventoso, vero?<\/p>\n<p>In JavaScript, c&#8217;\u00e8 questo stesso problema della mutazione. Se il vostro codice \u00e8 mutabile, potreste cambiare (e rompere) qualcosa senza saperlo.<\/p>\n<div class=\"paragrafo\">\n<h2 id=\"section1\">In JavaScript, gli oggetti sono mutabili<\/h2>\n<p>In JavaScript, potete aggiungere delle propriet\u00e0 a un oggetto. Quando lo fate dopo averlo istanziato, l&#8217;oggetto \u00e8 cambiato per sempre. Muta, come muta un membro degli X-Men quando guadagna un potere.<\/p>\n<p>Nell&#8217;esempio seguente, la variabile <code>egg<\/code> muta quando gli si aggiunge la propriet\u00e0 <code>isBroken<\/code>. Diciamo che gli oggetti (come <code>egg<\/code>) sono mutabili (hanno la capacit\u00e0 di <i>mutare<\/i>).<\/p>\n<pre id=\"snippet1\" class=\" language-javascript\"><code class=\" language-javascript\">const egg <span class=\"token operator\">=<\/span> <span class=\"token punctuation\">{<\/span> name<span class=\"token punctuation\">:<\/span> <span class=\"token string\">\"Humpty Dumpty\"<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span>\negg<span class=\"token punctuation\">.<\/span>isBroken <span class=\"token operator\">=<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">;<\/span>\n\nconsole<span class=\"token punctuation\">.<\/span>log<span class=\"token punctuation\">(<\/span>egg<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\n<span class=\"token comment\" spellcheck=\"true\">\/\/ {\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   name: \"Humpty Dumpty\",\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   isBroken: false\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/ }<\/span><\/code><\/pre>\n<p>La mutazione \u00e8 piuttosto normale in JavaScript. La usate sempre.<\/p>\n<p><strong>Ecco quando la mutazione diventa spaventosa.<\/strong><\/p>\n<p>Supponiamo di creare una constant variable chiamata <code>newEgg<\/code> e le assegnamo <code>egg<\/code>. Poi vogliamo cambiare il nome di <code>newEgg<\/code> con qualcosa d&#8217;altro.<\/p>\n<pre id=\"snippet2\" class=\" language-javascript\"><code class=\" language-javascript\">const egg <span class=\"token operator\">=<\/span> <span class=\"token punctuation\">{<\/span> name<span class=\"token punctuation\">:<\/span> <span class=\"token string\">\"Humpty Dumpty\"<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span>\n\nconst newEgg <span class=\"token operator\">=<\/span> egg<span class=\"token punctuation\">;<\/span>\nnewEgg<span class=\"token punctuation\">.<\/span>name <span class=\"token operator\">=<\/span> <span class=\"token string\">\"Errr ... Not Humpty Dumpty\"<\/span><span class=\"token punctuation\">;<\/span><\/code><\/pre>\n<p>Quando cambiate (mutate) <code>newEgg<\/code>, sapevate che <code>egg<\/code> viene mutato automaticamente?<\/p>\n<pre id=\"snippet3\" class=\" language-javascript\"><code class=\" language-javascript\">console<span class=\"token punctuation\">.<\/span>log<span class=\"token punctuation\">(<\/span>egg<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\n<span class=\"token comment\" spellcheck=\"true\">\/\/ {\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   name: \"Errr ... Not Humpty Dumpty\"\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/ }<\/span><\/code><\/pre>\n<p>L&#8217;esempio precedente illustra perch\u00e9 la mutazione pu\u00f2 fare paura: quando cambiate un pezzo del vostro codice, un altro pezzo pu\u00f2 cambiare da un&#8217;altra parte senza che lo sappiate. Come risultato, otterrete dei bug difficili da tracciare e sistemare.<\/p>\n<p>Questo strano comportamento avviene perch\u00e9 in JavaScrip gli oggetti vengono passati per riferimento.<\/p>\n<h3 id=\"section2\">In JavaScript gli oggetti sono passati per riferimento<\/h3>\n<p>Per capire cosa significa \u201cpassato per riferimento\u201d, per prima cosa dovete capire che ogni oggetto ha un&#8217;identit\u00e0 unica in JavaScript. Quando assegnate un oggetto a una variabile, collegate la variabile all&#8217;identit\u00e0 dell&#8217;oggetto (ossia, la passate per riferimento) piuttosto che assegnare la variabile direttamente al valore dell&#8217;oggetto. Questo \u00e8 il motivo per cui quando confrontate due oggetti diversi, ottenete <code>false<\/code> anche se gli oggetti hanno lo stesso valore.<\/p>\n<pre id=\"snippet4\" class=\" language-javascript\"><code class=\" language-javascript\">console<span class=\"token punctuation\">.<\/span>log<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><span class=\"token punctuation\">}<\/span> <span class=\"token operator\">==<\/span><span class=\"token operator\">=<\/span> <span class=\"token punctuation\">{<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token comment\" spellcheck=\"true\">\/\/ false<\/span><\/code><\/pre>\n<p>Quando assegnate <code>egg<\/code> a <code>newEgg<\/code>, <code>newEgg<\/code> punta allo stesso oggetto di <code>egg<\/code>. Dal momento che <code>egg<\/code> e <code>newEgg<\/code> sono la stessa cosa, quando cambiate <code>newEgg<\/code>, <code>egg<\/code> viene cambiato automaticamente.<\/p>\n<pre id=\"snippet5\" class=\" language-javascript\"><code class=\" language-javascript\">console<span class=\"token punctuation\">.<\/span>log<span class=\"token punctuation\">(<\/span>egg <span class=\"token operator\">==<\/span><span class=\"token operator\">=<\/span> newEgg<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token comment\" spellcheck=\"true\">\/\/ true<\/span><\/code><\/pre>\n<p>Sfortunatamente, la maggior parte delle volte, non vorrete che <code>egg<\/code> cambi con <code>newEgg<\/code>, dal momento che causa la rottura del vostro codice quanto meno ve lo aspettereste. Quindi, come evitiamo che gli oggetti mutino? Prima di comprendere come prevenire la mutazione degli oggetti, dovete sapere cosa \u00e8 immutabile in JavaScript.<\/p>\n<\/div>\n<div class=\"paragrafo\">\n<h2 id=\"section3\">I primitivi sono immutabili in JavaScript<\/h2>\n<p>In JavaScript, i primitivi (String, Number, Boolean, Null, Undefined e Symbol) sono immutabili: non potete cambiare la struttura (aggiungere propriet\u00e0 o metodi) di un primitivo. Non succede nulla anche se cercate di aggiungere propriet\u00e0 a un primitivo.<\/p>\n<pre id=\"snippet6\" class=\" language-javascript\"><code class=\" language-javascript\">const egg <span class=\"token operator\">=<\/span> <span class=\"token string\">\"Humpty Dumpty\"<\/span><span class=\"token punctuation\">;<\/span>\negg<span class=\"token punctuation\">.<\/span>isBroken <span class=\"token operator\">=<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">;<\/span>\n\nconsole<span class=\"token punctuation\">.<\/span>log<span class=\"token punctuation\">(<\/span>egg<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token comment\" spellcheck=\"true\">\/\/ Humpty Dumpty\n<\/span>console<span class=\"token punctuation\">.<\/span>log<span class=\"token punctuation\">(<\/span>egg<span class=\"token punctuation\">.<\/span>isBroken<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token comment\" spellcheck=\"true\">\/\/ undefined<\/span><\/code><\/pre>\n<\/div>\n<div class=\"paragrafo\">\n<h2 id=\"section4\"><code>const<\/code> non garantisce l&#8217;immutabilit\u00e0<\/h2>\n<p>Molte persone pensano che le variabili dichiarate con <code>const<\/code> siano immutabili. Questa \u00e8 una supposizione incorretta.<\/p>\n<p>Dichiarare una variabile con <code>const<\/code> non la rende immutabile: impedisce che gli assegniate un altro valore.<\/p>\n<pre id=\"snippet7\" class=\" language-javascript\"><code class=\" language-javascript\">const myName <span class=\"token operator\">=<\/span> <span class=\"token string\">\"Zell\"<\/span><span class=\"token punctuation\">;<\/span>\nmyName <span class=\"token operator\">=<\/span> <span class=\"token string\">\"Triceratops\"<\/span><span class=\"token punctuation\">;<\/span>\n<span class=\"token comment\" spellcheck=\"true\">\/\/ ERROR<\/span><\/code><\/pre>\n<p>Quando dichiarate un oggetto con <code>const<\/code>, vi \u00e8 ancora permesso far mutare l&#8217;oggetto. Nell&#8217;esempio <code>egg<\/code> precedente, anche se <code>egg<\/code> \u00e8 creato con <code>const<\/code>, <code>const<\/code> non impedisce che <code>egg<\/code> muti.<\/p>\n<pre id=\"snippet8\" class=\" language-javascript\"><code class=\" language-javascript\">const egg <span class=\"token operator\">=<\/span> <span class=\"token punctuation\">{<\/span> name<span class=\"token punctuation\">:<\/span> <span class=\"token string\">\"Humpty Dumpty\"<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span>\negg<span class=\"token punctuation\">.<\/span>isBroken <span class=\"token operator\">=<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">;<\/span>\n\nconsole<span class=\"token punctuation\">.<\/span>log<span class=\"token punctuation\">(<\/span>egg<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\n<span class=\"token comment\" spellcheck=\"true\">\/\/ {\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   name: \"Humpty Dumpty\",\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   isBroken: false\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/ }<\/span><\/code><\/pre>\n<\/div>\n<div class=\"paragrafo\">\n<h2 id=\"section5\">Impedire che gli oggetti mutino<\/h2>\n<p>Potete usare <code>Object.assign<\/code> e assignment per impedire che gli oggetti mutino.<\/p>\n<h3 id=\"section6\"><code>Object.assign<\/code><\/h3>\n<p><code>Object.assign<\/code> vi permette di combinare due (o pi\u00f9) oggetti insieme in uno singolo. Ha la sintassi seguente:<\/p>\n<pre id=\"snippet9\" class=\" language-javascript\"><code class=\" language-javascript\">const newObject <span class=\"token operator\">=<\/span> Object<span class=\"token punctuation\">.<\/span>assign<span class=\"token punctuation\">(<\/span>object1<span class=\"token punctuation\">,<\/span> object2<span class=\"token punctuation\">,<\/span> object3<span class=\"token punctuation\">,<\/span> object4<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/code><\/pre>\n<p><code>newObject<\/code> conterr\u00e0 delle propriet\u00e0 da tutti gli oggetti che avete passato in <code>Object.assign<\/code>.<\/p>\n<pre id=\"snippet10\" class=\" language-javascript\"><code class=\" language-javascript\">const papayaBlender <span class=\"token operator\">=<\/span> <span class=\"token punctuation\">{<\/span> canBlendPapaya<span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">true<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span>\nconst mangoBlender <span class=\"token operator\">=<\/span> <span class=\"token punctuation\">{<\/span> canBlendMango<span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">true<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span>\n\nconst fruitBlender <span class=\"token operator\">=<\/span> Object<span class=\"token punctuation\">.<\/span>assign<span class=\"token punctuation\">(<\/span>papayaBlender<span class=\"token punctuation\">,<\/span> mangoBlender<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\n\nconsole<span class=\"token punctuation\">.<\/span>log<span class=\"token punctuation\">(<\/span>fruitBlender<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\n<span class=\"token comment\" spellcheck=\"true\">\/\/ {\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   canBlendPapaya: true,\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   canBlendMango: true\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/ }<\/span><\/code><\/pre>\n<p>Se si trovano due propriet\u00e0 in contrasto, la propriet\u00e0 in un oggetto seguente sovrascrive la propriet\u00e0 in un oggetto precedente (nei parametri di <code>Object.assign<\/code> parameters).<\/p>\n<pre id=\"snippet11\" class=\" language-javascript\"><code class=\" language-javascript\">const smallCupWithEar <span class=\"token operator\">=<\/span> <span class=\"token punctuation\">{<\/span>\n  volume<span class=\"token punctuation\">:<\/span> <span class=\"token number\">300<\/span><span class=\"token punctuation\">,<\/span>\n  hasEar<span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">true<\/span>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span>\n\nconst largeCup <span class=\"token operator\">=<\/span> <span class=\"token punctuation\">{<\/span> volume<span class=\"token punctuation\">:<\/span> <span class=\"token number\">500<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span>\n\n<span class=\"token comment\" spellcheck=\"true\">\/\/ In this case, volume gets overwritten from 300 to 500\n<\/span>const myIdealCup <span class=\"token operator\">=<\/span> Object<span class=\"token punctuation\">.<\/span>assign<span class=\"token punctuation\">(<\/span>smallCupWithEar<span class=\"token punctuation\">,<\/span> largeCup<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\n\nconsole<span class=\"token punctuation\">.<\/span>log<span class=\"token punctuation\">(<\/span>myIdealCup<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\n<span class=\"token comment\" spellcheck=\"true\">\/\/ {\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   volume: 500,\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   hasEar: true\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/ }<\/span><\/code><\/pre>\n<p><strong>Ma attenzione! Quando combinate due oggetti con <code>Object.assign<\/code>, il primo oggetto viene mutato. Altri oggetti non vengono mutati.<\/strong><\/p>\n<pre id=\"snippet12\" class=\" language-javascript\"><code class=\" language-javascript\">console<span class=\"token punctuation\">.<\/span>log<span class=\"token punctuation\">(<\/span>smallCupWithEar<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\n<span class=\"token comment\" spellcheck=\"true\">\/\/ {\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   volume: 500,\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   hasEar: true\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/ }\n<\/span>\nconsole<span class=\"token punctuation\">.<\/span>log<span class=\"token punctuation\">(<\/span>largeCup<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><span class=\"token comment\" spellcheck=\"true\">\n\/\/ {\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   volume: 500\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/ }<\/span><\/code><\/pre>\n<h3 id=\"section7\">Risolvere il problema di mutazione di <code>Object.assign<\/code><\/h3>\n<p>Potete passare un nuovo oggetto come vostro primo oggetto per impedire che gli oggetti esistenti mutino. Muterete ancora il primo oggetto per\u00f2 (l&#8217;oggetto vuoto), ma va bene perch\u00e9 questa mutazione non interessa null&#8217;altro.<\/p>\n<pre id=\"snippet13\" class=\" language-javascript\"><code class=\" language-javascript\">const smallCupWithEar <span class=\"token operator\">=<\/span> <span class=\"token punctuation\">{<\/span>\n  volume<span class=\"token punctuation\">:<\/span> <span class=\"token number\">300<\/span><span class=\"token punctuation\">,<\/span>\n  hasEar<span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">true<\/span>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span>\n\nconst largeCup <span class=\"token operator\">=<\/span> <span class=\"token punctuation\">{<\/span>\n  volume<span class=\"token punctuation\">:<\/span> <span class=\"token number\">500<\/span>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span>\n\n<span class=\"token comment\" spellcheck=\"true\">\/\/ Using a new object as the first argument\n<\/span>const myIdealCup <span class=\"token operator\">=<\/span> Object<span class=\"token punctuation\">.<\/span>assign<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span> smallCupWithEar<span class=\"token punctuation\">,<\/span> largeCup<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/code><\/pre>\n<p>Potete mutare il vostro nuovo oggetto in qualunque modo vogliate d&#8217;ora in poi. Non interesser\u00e0 nessuno dei vostri oggetti precedenti.<\/p>\n<pre id=\"snippet14\" class=\" language-javascript\"><code class=\" language-javascript\">myIdealCup<span class=\"token punctuation\">.<\/span>picture <span class=\"token operator\">=<\/span> <span class=\"token string\">\"Mickey Mouse\"<\/span><span class=\"token punctuation\">;<\/span>\nconsole<span class=\"token punctuation\">.<\/span>log<span class=\"token punctuation\">(<\/span>myIdealCup<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\n<span class=\"token comment\" spellcheck=\"true\">\/\/ {\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   volume: 500,\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   hasEar: true,\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   picture: \"Mickey Mouse\"\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/ }\n<\/span><span class=\"token comment\" spellcheck=\"true\">\n\/\/ smallCupWithEar doesn't get mutated\n<\/span>console<span class=\"token punctuation\">.<\/span>log<span class=\"token punctuation\">(<\/span>smallCupWithEar<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><span class=\"token comment\" spellcheck=\"true\"> \/\/ { volume: 300, hasEar: true }\n<\/span><span class=\"token comment\" spellcheck=\"true\">\n\/\/ largeCup doesn't get mutated\n<\/span>console<span class=\"token punctuation\">.<\/span>log<span class=\"token punctuation\">(<\/span>largeCup<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><span class=\"token comment\" spellcheck=\"true\"> \/\/ { volume: 500 }<\/span><\/code><\/pre>\n<h3 id=\"section8\">Ma <code>Object.assign<\/code> copia i riferimenti agli oggetti<\/h3>\n<p>Il problema di <code>Object.assign<\/code> \u00e8 che fa uno <i>shallow merge<\/i>: copia le propriet\u00e0 direttamente da un oggetto all&#8217;altro. Quando lo fa, copia anche i riferimenti a qualsiasi oggetto.<\/p>\n<p>Spieghiamo questa affermazione con un esempio.<\/p>\n<p>Supponiamo che compriate un nuovo sound system. Il sistema vi permette di dichiarare se l&#8217;alimentazione \u00e8 accesa. Vi permette anche di impostare il volume, la quantit\u00e0 di bassi e altre opzioni.<\/p>\n<pre id=\"snippet15\" class=\" language-javascript\"><code class=\" language-javascript\">const defaultSettings <span class=\"token operator\">=<\/span> <span class=\"token punctuation\">{<\/span>\n  power<span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span>\n  soundSettings<span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">{<\/span>\n    volume<span class=\"token punctuation\">:<\/span> <span class=\"token number\">50<\/span><span class=\"token punctuation\">,<\/span>\n    bass<span class=\"token punctuation\">:<\/span> <span class=\"token number\">20<\/span><span class=\"token punctuation\">,<\/span>\n    <span class=\"token comment\" spellcheck=\"true\">\/\/ other options\n<\/span>  <span class=\"token punctuation\">}<\/span>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><\/code><\/pre>\n<p>A qualche vostro amico piace la musica rumorosa, quindi decidete di creare un preset che di sicuro sveglier\u00e0 i vostri vicini quando dormono.<\/p>\n<pre id=\"snippet16\" class=\" language-javascript\"><code class=\" language-javascript\">const loudPreset <span class=\"token operator\">=<\/span> <span class=\"token punctuation\">{<\/span>\n  soundSettings<span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">{<\/span>\n    volume<span class=\"token punctuation\">:<\/span> <span class=\"token number\">100<\/span>\n  <span class=\"token punctuation\">}<\/span>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><\/code><\/pre>\n<p>Poi invitate i vostri amici per una festa. Per preservare i vostri preset esistenti, cercate di combinare il preset rumoroso con quello di default.<\/p>\n<pre id=\"snippet17\" class=\" language-javascript\"><code class=\" language-javascript\">const partyPreset <span class=\"token operator\">=<\/span> Object<span class=\"token punctuation\">.<\/span>assign<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span> defaultSettings<span class=\"token punctuation\">,<\/span> loudPreset<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/code><\/pre>\n<p>Ma <code>partyPreset<\/code> suona strano: il volume \u00e8 sufficientemente alto ma i bassi sono inesistenti. Quando ispezionate <code>partyPreset<\/code>, siete sorpresi di non trovarci alcun basso!<\/p>\n<pre id=\"snippet18\" class=\" language-javascript\"><code class=\" language-javascript\">console<span class=\"token punctuation\">.<\/span>log<span class=\"token punctuation\">(<\/span>partyPreset<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\n<span class=\"token comment\" spellcheck=\"true\">\/\/ {\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   power: true,\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   soundSettings: {\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/     volume: 100\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   }\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/ }<\/span><\/code><\/pre>\n<p>Questo succede perch\u00e9 JavaScript copia il riferimento all&#8217;oggetto <code>soundSettings<\/code>. Dal momento che sia <code>defaultSettings<\/code> sia <code>loudPreset<\/code> hanno un oggetto <code>soundSettings<\/code>, quello che viene dopo viene copiato nel nuovo oggetto.<\/p>\n<p>Se cambiate <code>partyPreset<\/code>, <code>loudPreset<\/code> muter\u00e0 di conseguenza: prova del fatto che il riferimento a <code>soundSettings<\/code> viene copiato.<\/p>\n<pre id=\"snippet19\" class=\" language-javascript\"><code class=\" language-javascript\">partyPreset<span class=\"token punctuation\">.<\/span>soundSettings<span class=\"token punctuation\">.<\/span>bass <span class=\"token operator\">=<\/span> <span class=\"token number\">50<\/span><span class=\"token punctuation\">;<\/span>\n\nconsole<span class=\"token punctuation\">.<\/span>log<span class=\"token punctuation\">(<\/span>loudPreset<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\n<span class=\"token comment\" spellcheck=\"true\">\/\/ {\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   soundSettings: {\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/     volume: 100,\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/     bass: 50\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   }\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/ }\n<\/span><\/code><\/pre>\n<p>Dal momento che <code>Object.assign<\/code> fa uno shallow merge, dovete usare un altro metodo per fare il merge degli oggetti che contengono delle propriet\u00e0 annidate (ossia, oggetti all&#8217;interno di oggetti).<\/p>\n<p>Entra in scena assignment.<\/p>\n<h3 id=\"section9\">assignment<\/h3>\n<p><a href=\"https:\/\/github.com\/bevacqua\/assignment\/blob\/master\/assignment.js\">assignment<\/a> \u00e8 una piccola libreria creata da <a href=\"https:\/\/twitter.com\/nzgb\">Nicol\u00e1s Bevacqua<\/a> di <a href=\"https:\/\/ponyfoo.com\/\">Pony Foo<\/a>, un&#8217;ottima fonte di conoscenza JavaScript. Vi aiuta a fare un deep merge senza dovervi preoccupare della mutazione. A parte il nome del metodo, la sintassi \u00e8 la stessa di <code>Object.assign<\/code>.<\/p>\n<pre id=\"snippet20\" class=\" language-javascript\"><code class=\" language-javascript\"><span class=\"token comment\" spellcheck=\"true\">\/\/ Perform a deep merge with assignment\n<\/span>const partyPreset <span class=\"token operator\">=<\/span> assignment<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span> defaultSettings<span class=\"token punctuation\">,<\/span> loudPreset<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\n\nconsole<span class=\"token punctuation\">.<\/span>log<span class=\"token punctuation\">(<\/span>partyPreset<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><span class=\"token comment\" spellcheck=\"true\">\n\/\/ {\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   power: true,\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   soundSettings: {\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/     volume: 100,\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/     bass: 20\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   }\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/ }<\/span><\/code><\/pre>\n<p>assignment copia i valori di tutti gli oggetti annidati, il che impedisce agli oggetti esistenti di venir mutati.<\/p>\n<p>Se cercate di cambiare una qualsiasi propriet\u00e0 in <code>partyPreset.soundSettings<\/code> adesso, vedrete che <code>loudPreset<\/code> rimarr\u00e0 com&#8217;era.<\/p>\n<pre id=\"snippet21\" class=\" language-javascript\"><code class=\" language-javascript\">partyPreset<span class=\"token punctuation\">.<\/span>soundSettings<span class=\"token punctuation\">.<\/span>bass <span class=\"token operator\">=<\/span> <span class=\"token number\">50<\/span><span class=\"token punctuation\">;<\/span>\n\n<span class=\"token comment\" spellcheck=\"true\">\/\/ loudPreset doesn't get mutated\n<\/span>console<span class=\"token punctuation\">.<\/span>log<span class=\"token punctuation\">(<\/span>loudPreset<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\n<span class=\"token comment\" spellcheck=\"true\">\/\/ {\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   soundSettings {\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/     volume: 100\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   }\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/ }<\/span><\/code><\/pre>\n<p>assignment \u00e8 solo una della molte librerie che vi aiutano a fare un deep merge. Anche altre librerie, incluse <a href=\"https:\/\/lodash.com\/docs#merge\">lodash.merge<\/a> e <a href=\"https:\/\/www.npmjs.com\/package\/merge-options\">merge-options<\/a>, possono aiutarvi a farlo. Sentitevi liberi di scegliere una di queste librerie.<\/p>\n<h3 id=\"section10\">Dovete sempre usare assignment invece di <code>Object.assign<\/code>?<\/h3>\n<p>Fintanto che sapete come impedire che i vostri oggetti mutino, potete usare <code>Object.assign<\/code>. Non ci sono conseguenze nell&#8217;usarlo fintanto che sapete come usarlo in maniera appropriata.<\/p>\n<p>Tuttavia, se dovete assegnare oggetti con propriet\u00e0 annidate, preferite sempre un deep merge a <code>Object.assign<\/code>.<\/p>\n<h3 id=\"section11\">Assicurarsi che gli oggetti non mutino<\/h3>\n<p>Sebbene i metodi citati possano aiutarvi a prevenire le mutazioni degli oggetti, non garantiscono che gli oggetti non mutino. Se avete fatto un errore e avete usato <code>Object.assign<\/code> per un oggetto annidato, avrete dei problemi in seguito.<\/p>\n<p>Per tutelarvi, potreste voler garantire che gli oggetti non subiscano alcuna mutazione. Per farlo, potete usare librerie come <a href=\"https:\/\/facebook.github.io\/immutable-js\/\">ImmutableJS<\/a>. Questa libreria d\u00e0 un errore ogni volta che cercate di mutare un oggetto.<\/p>\n<p>In alternativa, potete usare <code>Object.freeze<\/code> e deep-freeze. Questi due metodi fanno un fail silenzioso (nessun throw error, ma non mutano nemmeno gli oggetti).<\/p>\n<h3 id=\"section12\"><code>Object.freeze<\/code> e deep-freeze<\/h3>\n<p><code>Object.freeze<\/code> impedisce che le propriet\u00e0 dirette di un oggetto cambino.<\/p>\n<pre id=\"snippet22\" class=\" language-javascript\"><code class=\" language-javascript\">const egg <span class=\"token operator\">=<\/span> <span class=\"token punctuation\">{<\/span>\n  name<span class=\"token punctuation\">:<\/span> <span class=\"token string\">\"Humpty Dumpty\"<\/span><span class=\"token punctuation\">,<\/span>\n  isBroken<span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">false<\/span>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span>\n\n<span class=\"token comment\" spellcheck=\"true\">\/\/ Freezes the egg\n<\/span>Object<span class=\"token punctuation\">.<\/span>freeze<span class=\"token punctuation\">(<\/span>egg<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\n\n<span class=\"token comment\" spellcheck=\"true\">\/\/ Attempting to change properties will silently fail\n<\/span>egg<span class=\"token punctuation\">.<\/span>isBroken <span class=\"token operator\">=<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">;<\/span>\n\nconsole<span class=\"token punctuation\">.<\/span>log<span class=\"token punctuation\">(<\/span>egg<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token comment\" spellcheck=\"true\">\/\/ { name: \"Humpty Dumpty\", isBroken: false }<\/span><\/code><\/pre>\n<p>Ma non aiuta quando mutate una propriet\u00e0 pi\u00f9 profonda come <code>defaultSettings.soundSettings.base<\/code>.<\/p>\n<pre id=\"snippet23\" class=\" language-javascript\"><code class=\" language-javascript\">const defaultSettings <span class=\"token operator\">=<\/span> <span class=\"token punctuation\">{<\/span>\n  power<span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span>\n  soundSettings<span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">{<\/span>\n    volume<span class=\"token punctuation\">:<\/span> <span class=\"token number\">50<\/span><span class=\"token punctuation\">,<\/span>\n    bass<span class=\"token punctuation\">:<\/span> <span class=\"token number\">20<\/span>\n  <span class=\"token punctuation\">}<\/span>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span>\nObject<span class=\"token punctuation\">.<\/span>freeze<span class=\"token punctuation\">(<\/span>defaultSettings<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\ndefaultSettings<span class=\"token punctuation\">.<\/span>soundSettings<span class=\"token punctuation\">.<\/span>bass <span class=\"token operator\">=<\/span> <span class=\"token number\">100<\/span><span class=\"token punctuation\">;<\/span>\n\n<span class=\"token comment\" spellcheck=\"true\">\/\/ soundSettings gets mutated nevertheless\n<\/span>console<span class=\"token punctuation\">.<\/span>log<span class=\"token punctuation\">(<\/span>defaultSettings<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\n<span class=\"token comment\" spellcheck=\"true\">\/\/ {\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   power: true,\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   soundSettings: {\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/     volume: 50,\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/     bass: 100\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   }\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/ }<\/span><\/code><\/pre>\n<p>Per impedire una mutazione profonda, potete usare una libreria chiamata <a href=\"https:\/\/www.npmjs.com\/package\/deep-freeze\">deep-freeze<\/a>, che chiama ricorsivamente <code>Object.freeze<\/code> su tutti gli oggetti.<\/p>\n<pre id=\"snippet24\" class=\" language-javascript\"><code class=\" language-javascript\">const defaultSettings <span class=\"token operator\">=<\/span> <span class=\"token punctuation\">{<\/span>\n  power<span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span>\n  soundSettings<span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">{<\/span>\n    volume<span class=\"token punctuation\">:<\/span> <span class=\"token number\">50<\/span><span class=\"token punctuation\">,<\/span>\n    bass<span class=\"token punctuation\">:<\/span> <span class=\"token number\">20<\/span>\n  <span class=\"token punctuation\">}<\/span>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span>\n\n<span class=\"token comment\" spellcheck=\"true\">\/\/ Performing a deep freeze (after including deep-freeze in your code per instructions on npm)\n<\/span>deepFreeze<span class=\"token punctuation\">(<\/span>defaultSettings<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\n\n<span class=\"token comment\" spellcheck=\"true\">\/\/ Attempting to change deep properties will fail silently\n<\/span>defaultSettings<span class=\"token punctuation\">.<\/span>soundSettings<span class=\"token punctuation\">.<\/span>bass <span class=\"token operator\">=<\/span> <span class=\"token number\">100<\/span><span class=\"token punctuation\">;<\/span>\n\n<span class=\"token comment\" spellcheck=\"true\">\/\/ soundSettings doesn't get mutated anymore\n<\/span>console<span class=\"token punctuation\">.<\/span>log<span class=\"token punctuation\">(<\/span>defaultSettings<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\n<span class=\"token comment\" spellcheck=\"true\">\/\/ {\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   power: true,\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   soundSettings: {\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/     volume: 50,\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/     bass: 20\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/   }\n<\/span><span class=\"token comment\" spellcheck=\"true\">\/\/ }<\/span><\/code><\/pre>\n<\/div>\n<div class=\"paragrafo\">\n<h2 id=\"section13\">Non confondete il riassegnamento con la mutazione<\/h2>\n<p>Quando riassegnate una variabile, cambiate quello a cui punta. Nell&#8217;esempio seguente, <code>a<\/code> \u00e8 cambiato da <code>11<\/code> a <code>100<\/code>.<\/p>\n<pre id=\"snippet25\" class=\" language-javascript\"><code class=\" language-javascript\"><span class=\"token keyword\">let<\/span> <span class=\"token number\">a<\/span> <span class=\"token operator\">=<\/span> <span class=\"token number\">11<\/span><span class=\"token punctuation\">;<\/span>\n<span class=\"token number\">a<\/span> <span class=\"token operator\">=<\/span> <span class=\"token number\">100<\/span><span class=\"token punctuation\">;<\/span><\/code><\/pre>\n<p>Quando mutate un oggetto, esso viene cambiato. Il riferimento all&#8217;oggetto rimane lo stesso.<\/p>\n<pre id=\"snippet26\" class=\" language-javascript\"><code class=\" language-javascript\">const egg <span class=\"token operator\">=<\/span> <span class=\"token punctuation\">{<\/span> name<span class=\"token punctuation\">:<\/span> <span class=\"token string\">\"Humpty Dumpty\"<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span>\negg<span class=\"token punctuation\">.<\/span>isBroken <span class=\"token operator\">=<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">;<\/span><\/code><\/pre>\n<\/div>\n<div class=\"paragrafo\">\n<h2 id=\"section14\">Conclusioni<\/h2>\n<p>La mutazione fa paura perch\u00e9 pu\u00f2 causare la rottura del vostro codice senza che lo sappiate. Anche se sospettate che la causa della rottura sia una mutazione, pu\u00f2 essere difficile per voi definire con precisione quale parte del codice ha creato la mutazione. Quindi, il modo migliore per impedire che il codice smetta di funzionare senza saperlo \u00e8 assicurarsi che gli oggetti non mutino fin dall&#8217;inizio.<\/p>\n<p>Per impedire che gli oggetti mutino, potete usare delle librerie quali <a href=\"https:\/\/facebook.github.io\/immutable-js\/\">ImmutableJS<\/a> e <a href=\"https:\/\/github.com\/swannodette\/mori\">Mori.js<\/a>, o usare <code>Object.assign<\/code> e <code>Object.freeze<\/code>.<\/p>\n<p>Prendete nota che <code>Object.assign<\/code> e <code>Object.freeze<\/code> possono solo impedire che le propriet\u00e0 dirette mutino. Se dovete impedire che livelli multipli di oggetti mutino, avrete bisogno di librerie come <a href=\"https:\/\/github.com\/bevacqua\/assignment\/blob\/master\/assignment.js\">assignment<\/a> e <a href=\"https:\/\/www.npmjs.com\/package\/deep-freeze\">deep-freeze<\/a>.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>I cambiamenti inaspettati nel vostro codice JavaScript possono essere dei veri grattacapi. Pu\u00f2 essere ancora pi\u00f9 difficile prevenire questi cambiamenti involontari, quando si lavora con gli oggetti. Zell Liew ci mostra alcuni trucchi (e librerie) per prevenire questi cambiamenti non intenzionali e assicurare la stabilit\u00e0 quando si lavora con gli oggetti.<\/p>\n","protected":false},"author":818,"featured_media":7000845,"comment_status":"open","ping_status":"open","template":"","categories":[4,271,218],"tags":[],"coauthors":[529],"class_list":["post-841","article","type-article","status-publish","has-post-thumbnail","hentry","category-codice","category-javascript","category-numero-240-11-gennaio-2018"],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/article\/841","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/article"}],"about":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/types\/article"}],"author":[{"embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/users\/818"}],"replies":[{"embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/comments?post=841"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/media\/7000845"}],"wp:attachment":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/media?parent=841"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/categories?post=841"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/tags?post=841"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/coauthors?post=841"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}