[ Web Proxy ]
URL:
Viewing: https://it.javascript.info/destructuring-assignment [Back]  [Original]

Assegnamento di destrutturazione
IT

Vorremo rendere disponibile questo progetto open-source per persone in tutto il mondo.

Aiutaci a tradurre il contenuto di questo tutorial nella tua lingua!

    Cerca in Javascript.info:
    Cerca nel tutorial:
    Light themeDark theme
    DanskEnglishEspaolFranaisIndonesiaItalianoTrkeOzbek

    Assegnamento di destrutturazione

    Le due strutture dati pi utilizzate in JavaScript sono Object e Array.

    • Gli oggetti ci consentono di creare ununica entit che memorizza elementi nel formato chiave-valore
    • Gli array ci consentono di raccogliere elementi in elenchi ordinati.

    A volte, quando li passiamo ad una funzione, potrebbe non essere necessario tutto loggetto/array, ma solo una parte di esso.

    Lassegnamento di destrutturazione (Destructuring assignment) una speciale sintassi che ci consente di spacchettare oggetti o array in gruppi di variabili; questo a volte risulta molto conveniente.

    La destrutturazione funziona alla grande anche con funzioni complesse che hanno molti parametri, valori predefiniti e cos via. Presto lo vedremo.

    Destrutturazione di un array

    Ecco un esempio di come un array viene destrutturato in variabili:

    // abbiamo un array con nome e cognome
    let arr = ["John", "Smith"]
    
    // assegnamento di destrutturazione
    // imposta firstName = arr[0]
    // e surname = arr[1]
    let [firstName, surname] = arr;
    
    alert(firstName); // John
    alert(surname);  // Smith

    Ora possiamo lavorare con le variabili invece che con gli elementi dellarray.

    Risulta utilissima se combinata con split o altri metodi che ritornano un array:

    let [firstName, surname] = "John Smith".split(' ');
    alert(firstName); // John
    alert(surname);  // Smith

    Come puoi vedere, la sintassi semplice. Ci sono per molti dettagli peculiari. Vediamo altri esempi, per capirlo meglio.

    Destrutturazione non significa distruzione.

    Viene chiamato assegnamento di destrutturazione perch destruttura copiando gli elementi allinterno di variabili. Ma larray in s non viene modificato.

    E solo un modo breve per scrivere:

    // let [firstName, surname] = arr;
    let firstName = arr[0];
    let surname = arr[1];
    Ignora gli elementi usando la virgola

    Gli elementi indesiderati dellarray possono essere ignorati tramite una virgola aggiuntiva:

    // il secondo elemento non  necessario
    let [firstName, , title] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];
    
    alert( title ); // Consul

    Nel codice sopra, il secondo elemento viene saltato, il terzo viene assegnato a title, il resto degli elementi vengono ignorati (visto che per loro non ci sono variabili).

    Funziona con qualsiasi iterabile alla destra

    In realt, possiamo utilizzarlo con qualsiasi iterabile, non solamente con un array:

    let [a, b, c] = "abc"; // ["a", "b", "c"]
    let [one, two, three] = new Set([1, 2, 3]);

    Funziona, perch internamente unassegnazione di destrutturazione lavora iterando sul valore a destra. E una specie di zucchero sintattico per chiamare for..of sul valore a destra di =, assegnandone i valori.

    Assegna a qualsiasi cosa ci sia dalla parte sinistra

    Possiamo inserire qualsiasi cosa assegnabile a sinistra.

    Ad esempio, la propriet di un oggetto:

    let user = {};
    [user.name, user.surname] = "John Smith".split(' ');
    
    alert(user.name); // John
    alert(user.surname); // Smith
    Eseguire cicli con .entries()

    Nel capitolo precedente abbiamo visto il metodo Object.entries(obj).

    Possiamo utilizzarlo con la destrutturazione per eseguire cicli sulle coppie chiave/valore di un oggetto:

    let user = {
      name: "John",
      age: 30
    };
    
    // ciclo su chiavi/valori
    for (let [key, value] of Object.entries(user)) {
      alert(`${key}:${value}`); // name:John, poi age:30
    }

    Un codice simile usando Map pi semplice, visto che iterabile:

    let user = new Map();
    user.set("name", "John");
    user.set("age", "30");
    
    // Map itera le coppie [key, value], molto comodo per la destrutturazione
    for (let [key, value] of user) {
      alert(`${key}:${value}`); // name:John, then age:30
    }
    Il trucco dello scambio di variabili

    c un trucco molto conosciuto per scambiare i valori di due variabili usando lassegnamento di destrutturazione:

    let guest = "Jane";
    let admin = "Pete";
    
    // Scambio dei valori: rende guest=Pete, admin=Jane
    [guest, admin] = [admin, guest];
    
    alert(`${guest} ${admin}`); // Pete Jane (scambiati con successo!)

    Nellesempio creiamo un array temporaneo con due varibili e lo destrutturiamo immediatamente invertendo lordine delle variabili. Nello stesso modo potremmo scambiare i valori di pi variabili.

    Loperatore rest

    Di solito, se larray pi lungo della lista a sinistra, gli elementi in eccesso vengono ignorati.

    Ad esempio, qui vengono presi solo i primi 2 elementi, i restanti vengono semplicemente ignorati:

    let [name1, name2] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];
    
    alert(name1); // Julius
    alert(name2); // Caesar
    
    // Gli elementi successivi non vengono assegnati

    Se vogliamo ottenere anche tutto ci che segue, possiamo aggiungere un altro parametro che raccoglie il resto utilizzando tre punti " ... ":

    let [name1, name2, ...rest] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];
    
    // rest  un array con gli elementi a destra, partendo dal terzo
    alert(rest[0]); // Consul
    alert(rest[1]); // of the Roman Republic
    alert(rest.length); // 2

    La variabile rest un array con i valori rimanenti dellarray a destra.

    Possiamo utilizzare qualsiasi altro nome di variabile al posto di rest; sufficiente accertarsi di inserire i tre punti prima del nome e di posizionarlo alla fine nellassegnamento di destrutturazione.

    let [name1, name2, ...titles] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];
    // now titles = ["Consul", "of the Roman Republic"]

    Valori di default

    Se ci sono meno elementi nellarray delle variabili da assegnare, non ci sar alcun errore. I valori assenti vengono considerati undefined:

    let [firstName, surname] = [];
    
    alert(firstName); // undefined
    alert(surname); // undefined

    Se volessimo assegnare un nostro valore di default, potremmo indicarlo con la sintassi =:

    // valori di default
    let [name = "Guest", surname = "Anonymous"] = ["Julius"];
    
    alert(name);    // Julius (dall'array)
    alert(surname); // Anonymous (valore di default)

    I valori di default possono essere anche espressioni complesse o chiamate a funzione. Verranno presi in considerazione solamente se non verr fornito alcun valore.

    Ad esempio, qui usiamo la funzione prompt per due defaults:

    // viene eseguito solo il prompt per il cognome
    let [name = prompt('name?'), surname = prompt('surname?')] = ["Julius"];
    
    alert(name);    // Julius (dall'array)
    alert(surname); // qualsiasi cosa provenga dal prompt

    Attenzione: la funzione prompt verr eseguita solo per il valore mancante (surname).

    Destrutturazione di oggetti

    Lassegnamento di destrutturazione funziona anche con gli oggetti.

    La sintassi :

    let {var1, var2} = {var1:, var2:}

    Abbiamo un oggetto alla destra dellassegnazione, che vogliamo dividere in variabili. Nel lato sinistro abbiamo un pattern di propriet corrispondenti. In questo semplice caso, abbiamo una lista di variabili raggruppate tra parentesi {...}.

    Ad esempio:

    let options = {
      title: "Menu",
      width: 100,
      height: 200
    };
    
    let {title, width, height} = options;
    
    alert(title);  // Menu
    alert(width);  // 100
    alert(height); // 200

    Le propriet options.title, options.width e options.height vengono assegnate alle variabili corrispondenti.

    Lordine non ha importanza. Questo codice funzionerebbe comunque:

    // cambiato l'ordine delle propriet in let {...}
    let {height, width, title} = { title: "Menu", height: 200, width: 100 }

    Il pattern a sinistra potrebbe essere anche pi complesso e specificare una mappatura tra propriet e variabili.

    Se volessimo assegnare una propriet ad una variabile con un altro nome, ad esempio la propriet options.width ad una variabile chiamata w, allora possiamo specificarlo con i due punti:

    let options = {
      title: "Menu",
      width: 100,
      height: 200
    };
    
    // { sourceProperty: targetVariable }
    let {width: w, height: h, title} = options;
    
    // width -> w
    // height -> h
    // title -> title
    
    alert(title);  // Menu
    alert(w);      // 100
    alert(h);      // 200

    I due punti specificano cosa : va dove. Nellesempio sopra la propriet width va in w, la propriet height va in h, e title viene assegnata ad una variabile con lo stesso nome.

    Per delle potenziali propriet mancanti possiamo impostare dei valori di default utilizzando "=", come nellesempio:

    let options = {
      title: "Menu"
    };
    
    let {width = 100, height = 200, title} = options;
    
    alert(title);  // Menu
    alert(width);  // 100
    alert(height); // 200

    Proprio come nel caso degli array o dei parametri di funzione, i valori di default possono essere espressioni pi complesse o chiamate a funzioni. Questi verranno valutati solo nel caso in cui il valore non verr fornito.

    Il codice richieder tramite prompt la width (larghezza), ma non il title (titolo):

    let options = {
      title: "Menu"
    };
    
    let {width = prompt("width?"), title = prompt("title?")} = options;
    
    alert(title);  // Menu
    alert(width);  // (qualsiasi cosa arrivi dal prompt)

    Possiamo anche combinare entrambi, i due punti e luguaglianza:

    let options = {
      title: "Menu"
    };
    
    let {width: w = 100, height: h = 200, title} = options;
    
    alert(title);  // Menu
    alert(w);      // 100
    alert(h);      // 200

    Se abbiamo un oggetto complesso con molte propriet, possiamo estrarre solamente ci che ci serve:

    let options = {
      title: "Menu",
      width: 100,
      height: 200
    };
    
    // estraiamo solamente title come propriet
    let { title } = options;
    
    alert(title); // Menu

    Il modello rest

    Cosa succede se loggetto possiede pi propriet delle variabili da noi fornite? Possiamo prenderne solamente alcune ed assegnare tutto ci che avanza da unaltra parte?

    La specifica per lutilizzo delloperatore rest ... fa quasi parte dello standard, ma molti browser non lo supportano ancora.

    Appare cosi:

    let options = {
      title: "Menu",
      height: 200,
      width: 100
    };
    
    // title = propriet con il titolo
    // rest = oggetto con il resto dei parametri
    let {title, ...rest} = options;
    
    // ora title="Menu", rest={height: 200, width: 100}
    alert(rest.height);  // 200
    alert(rest.width);   // 100
    Catturare senza let

    Negli esempi sopra le variabili vengono dichiarate appena prima di essere assegnate: let {} = {}. Ovviamente, potremmo anche utilizzare delle variabili gi esistenti. Ma c un tranello.

    Questo non funzionerebbe:

    let title, width, height;
    
    // errore in questa riga
    {title, width, height} = {title: "Menu", width: 200, height: 100};

    Il problema che JavaScript tratta {...} come un blocco di codice. Questo blocco di codice pu essere utilizzato per raggruppare istruzioni, come nellesempio:

    {
      // un blocco di codice
      let message = "Hello";
      // ...
      alert( message );
    }

    Per informare JavaScript che non ci troviamo in un blocco di codice, possiamo raggruppare lintera assegnazione tra parentesi (...):

    let title, width, height;
    
    // ora funziona
    ({title, width, height} = {title: "Menu", width: 200, height: 100});
    
    alert( title ); // Menu

    Destrutturazione annidata

    Se un oggetto o un array contiene altri oggetti o array, possiamo utilizzare sequenze (pattern) di estrazione pi complesse per andare pi in profondit con lestrazione.

    Nel codice sotto options possiede un ulteriore oggetto nella propriet size ed un array nella propriet items. Il pattern alla sinistra dellassegnazione ha la stessa struttura:

    let options = {
      size: {
        width: 100,
        height: 200
      },
      items: ["Cake", "Donut"],
      extra: true    // qualche extra che non destruttureremo
    };
    
    // destructuring assignment split in multiple lines for clarity
    let {
      size: { // mettiamo size qui
        width,
        height
      },
      items: [item1, item2], // assegniamo gli items qui
      title = "Menu" // non presente nell'oggetto (viene utilizzato il valore di default)
    } = options;
    
    alert(title);  // Menu
    alert(width);  // 100
    alert(height); // 200
    alert(item1);  // Cake
    alert(item2);  // Donut

    Lintero oggetto options ad eccezione di extra, il quale non viene menzionato, viene assegnato alle corrispondenti variabili.

    []

    Infine, abbiamo width, height, item1, item2 e title che assumono il valore di default.

    Nota che non ci sono variabili per size e items: prendiamo invece il loro contenuto. Questo accade spesso con lassegnamento di destrutturazione. Abbiamo un oggetto complesso e vogliamo estrarre solamente ci di cui abbiamo bisogno.

    Parametri di funzione intelligenti

    Ci sono casi in cui una funzione pu accettare pi parametri, molti dei quali opzionali. Questo vero specialmente per le interfacce utente. Immaginate una funzione che crea un menu. Pu avere una larghezza, unaltezza, un titolo, una lista di elementi e molto altro.

    Vediamo un pessimo modo per scrivere questo tipo di funzioni:

    function showMenu(title = "Untitled", width = 200, height = 100, items = []) {
      // ...
    }

    Nella vita reale, il problema ricordarsi lordine degli argomenti. Solitamente gli IDE ci aiutano in questo, specialmente se il codice ben documentato, eppure Un ulteriore problema quello di chiamare una funzione nel caso in cui molti parametri ci vadano bene di default.

    Come qui?

    // undefined where default values are fine
    showMenu("My Menu", undefined, undefined, ["Item1", "Item2"])

    E brutto a vedersi. E diventa illeggibile quando il numero di parametri aumenta.

    La destrutturazione ci viene in soccorso!

    Possiamo passare i parametri come un oggetto, e la funzione immediatamente lo destrutturizzer in variabili:

    // passiamo l'oggetto alla funzione
    let options = {
      title: "My menu",
      items: ["Item1", "Item2"]
    };
    
    // ...e immediatamente lo distribuisce alle variabili
    function showMenu({title = "Untitled", width = 200, height = 100, items = []}) {
      // title, items  presi da options,
      // width, height  valori di default
      alert( `${title} ${width} ${height}` ); // My Menu 200 100
      alert( items ); // Item1, Item2
    }
    
    showMenu(options);

    Possiamo anche utilizzare una destrutturazione pi complessa con oggetti annidati e diverse mappature:

    let options = {
      title: "My menu",
      items: ["Item1", "Item2"]
    };
    
    function showMenu({
      title = "Untitled",
      width: w = 100,  // width va su w
      height: h = 200, // height va su h
      items: [item1, item2] // il primo elemento va su item1, il secondo su item2
    }) {
      alert( `${title} ${w} ${h}` ); // My Menu 100 200
      alert( item1 ); // Item1
      alert( item2 ); // Item2
    }
    
    showMenu(options);

    La sintassi la stessa dellassegnamento di destrutturazione:

    function({
      incomingProperty: varName = defaultValue
      ...
    })

    Da notare che la destrutturazione presuppone che showMenu() abbia un argomento. Se vogliamo tutti i valori di default, allora dovremmo specificare un oggetto vuoto:

    showMenu({}); // ok, tutti i valori sono di default
    
    showMenu(); // questo dar errore

    Possiamo farlo ponendo {} come valore di default per lintera destrutturazione:

    // parametri semplificati per chiarezza
    function showMenu({ title = "Menu", width = 100, height = 200 } = {}) {
      alert( `${title} ${width} ${height}` );
    }
    
    showMenu(); // Menu 100 200

    Nel codice sopra, loggetto degli argomenti {} di default, quindi ci sar sempre qualcosa da destrutturare.

    Riepilogo

    • Lassegnamento di destrutturazione ci consente di mappare un oggetto o un array passandolo a variabili.

    • La sintassi per gli oggetti:

      let {prop : varName = default, ...rest} = object

      Questo significa che la propriet prop dovrebbe andare nella variabile varName e, se non esiste alcuna propriet, allora verr utilizzato il valore di default.

    • La sintassi per gli array:

      let [item1 = default, item2, ...rest] = array

      Il primo elemento va in item1; il secondo va in item2, tutti gli altri finiscono nellarray rest.

    • Per casi pi complessi, la parte sinistra deve possedere la stessa struttura di quella destra.

    Esercizi

    importanza: 5

    Abbiamo un oggetto:

    let user = {
      name: "John",
      years: 30
    };

    Scrivete lassegnamento di destrutturazione che legge:

    • la propriet name nella variabile name.
    • la propriet years nella variabile age.
    • la propriet isAdmin nella variabile isAdmin (falsa se assente)

    I valori dopo lassegnazione dovrebbero essere:

    let user = { name: "John", years: 30 };
    
    // il tuo codice a sinistra:
    // ... = user
    
    alert( name ); // John
    alert( age ); // 30
    alert( isAdmin ); // false
    soluzione
    let user = {
      name: "John",
      years: 30
    };
    
    let {name, years: age, isAdmin = false} = user;
    
    alert( name ); // John
    alert( age ); // 30
    alert( isAdmin ); // false
    importanza: 5

    Abbiamo un oggetto salaries:

    let salaries = {
      "John": 100,
      "Pete": 300,
      "Mary": 250
    };

    Create la funzione topSalary(salaries) che ritorna il nome della persona con il salario maggiore.

    • Se salaries vuoto, dovrebbe ritornare null.
    • Se ci sono pi persone con lo stesso salario massimo, ritornatene una.

    P.S. utilizzate Object.entries e la destrutturazione per iterare sulle coppie chiave/valore.

    Apri una sandbox con i test.

    soluzione
    function topSalary(salaries) {
    
      let maxSalary = 0;
      let maxName = null;
    
      for(const [name, salary] of Object.entries(salaries)) {
        if (maxSalary < salary) {
          maxSalary = salary;
          maxName = name;
        }
      }
    
      return maxName;
    }

    Apri la soluzione con i test in una sandbox.

    Mappa del tutorial

    Commenti

    leggi questo prima di lasciare un commento
    • Per qualsiasi suggerimento - per favore, apri una issue su GitHub o una pull request, piuttosto di lasciare un commento.
    • Se non riesci a comprendere quanto scitto nell'articolo ti preghiamo di fornire una spiegazione chiara.
    • Per inserire delle righe di codice utilizza il tag <code>, per molte righe includile nel tag <pre>, per pi di 10 righe utilizza una sandbox (plnkr, jsbin, codepen)

    Web Proxy Viewer  |  New URL  |  Original Page