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

Costruttore, operatore "new"
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

    Costruttore, operatore "new"

    La sintassi {...} ci consente di creare un oggetto. Ma spesso abbiamo bisogno di creare multipli oggetti simili, come ad esempio pi utenti, oggetti del menu e molto altro.

    Questo pu essere fatto utilizzando un costruttore e loperatore "new".

    Costruttore

    Tecnicamente un costruttore una normale funzione. Ma ci sono due convenzioni:

    1. Vengono denominati con la prima lettera maiuscola.
    2. Questi dovrebbero essere eseguiti solo con loperatore "new".

    Ad esempio:

    function User(name) {
      this.name = name;
      this.isAdmin = false;
    }
    
    let user = new User("Jack");
    
    alert(user.name); // Jack
    alert(user.isAdmin); // false

    Quando una funzione viene eseguita con new, esegue questi passaggi:

    1. Un nuovo oggetto, vuoto, viene creato ed assegnato a this.
    2. Viene eseguito il corpo della funzione. Solitamente questo modifica this, aggiungendo nuove propriet.
    3. Viene ritornato il valore assegnato a this.

    In altre parole, new User(...) fa qualcosa del genere:

    function User(name) {
      // this = {};  (implicito)
    
      // aggiungiamo propriet a this
      this.name = name;
      this.isAdmin = false;
    
      // return this;  (implicito)
    }

    Quindi let user = new User("Jack") d lo stesso risultato di:

    let user = {
      name: "Jack",
      isAdmin: false
    };

    Ora, se vogliamo creare altri utenti, possiamo chiamare new User("Ann"), new User("Alice") e cosi via. Molto pi rapido rispetto allutilizzare ogni volta oggetti letterali; risulta anche pi facile da leggere.

    Questo il principale scopo dei costruttori implementare codice riutilizzabile per la creazione di oggetti.

    Ribadiamo tecnicamente, ogni funzione (eccetto le arrow functions, siccome non hanno this) pu essere utilizzata come costruttore. Ovvero: ogni funzione pu essere eseguita con new. La prima lettera maiuscola semplicemente una convenzione, per rendere esplicito che la funzione deve essere eseguita con new.

    new function() { }

    Se abbiamo molte linee di codice utili alla creazione di un unico oggetto, possiamo raggrupparle in un costruttore richiamato contestualmente, come qui:

    // create a function and immediately call it with new
    let user = new function() {
      this.name = "John";
      this.isAdmin = false;
    
      // ...altro codice per la creazione di user
      // magari logiche complesse e istruzioni
      // variabili locali etc
    };

    Il costruttore non pu essere chiamato nuovamente, perch non salvato da nessuna parte; viene solo creato e chiamato. Questo trucco consente di incapsulare un codice che costruisce un singolo oggetto, senza necessit di riutilizzo futuro.

    Costruttori modalit test: new.target

    Tecniche avanzate

    La sintassi presentata nella seguente sezione viene utilizzata raramente; potete tranquillamente saltarla se non vi interessa sapere proprio tutto.

    Dentro la funzione, possiamo controllare quando questa viene chiamata con new e quando senza, utilizzando una speciale propriet new.target.

    Questa risulta undefined per le chiamate normali, mentre contiene la funzione se viene chiamata con new:

    function User() {
      alert(new.target);
    }
    
    // senza "new":
    User(); // undefined
    
    // con "new":
    new User(); // function User { ... }

    Questo pu essere utilizzato per consentire ad entrambe le chiamate di funzionare (con new e senza), quindi sia in in modalit costruttore che in modalit regolare.

    Possiamo anche fare in modo che le chiamate con new e quelle regolari facciano la stessa cosa, come in questo esempio:

    function User(name) {
      if (!new.target) { // se mi esegui senza new
        return new User(name); // ...Aggiungo new al posto tuo
      }
    
      this.name = name;
    }
    
    let john = User("John"); // reindirizza la chiamata a new User
    alert(john.name); // John

    Questo approccio viene adottato in alcune librerie per rendere la sintassi pi flessibile. Rende possibile la chiamata della funzione sia con new che senza.

    Ma non unottima cosa utilizzare la doppia sintassi ovunque, perch omettendo new il codice perde in leggibilit. Con la parola chiave new possiamo sapere con certezza che si sta creando un nuovo oggetto.

    Return nel costruttore

    Solitamente, i costruttori non hanno listruzione return. Il loro compito di eseguire tutto ci che necessario a creare loggetto lavorando su this; questultimo sar il risultato.

    Se decidiamo di inserire unistruzione di return, vanno seguite delle semplici regole:

    • Se return viene invocato con un oggetto, questo verr ritornato al posto di this.
    • Se return viene invocato con un tipo primitivo, verr ignorato.

    In altre parole, return con un oggetto ritorna quelloggetto; in tutti gli altri casi verr ritornato this.

    Ad esempio, qui return sovrascrive this ritornando un oggetto:

    function BigUser() {
    
      this.name = "John";
    
      return { name: "Godzilla" };  // <-- ritorna questo oggetto
    }
    
    alert( new BigUser().name );  // Godzilla

    Qui invece abbiamo un esempio con un return vuoto (potremmo anche ritornare un qualsiasi valore di tipo primitivo):

    function SmallUser() {
    
      this.name = "John";
    
      return; // <-- returns this
    }
    
    alert(new SmallUser().name);  //John

    Solitamente i costruttori non hanno listruzione return. Abbiamo comunque riportato, per completezza, quel che succede se si tenta di ritornare un oggetto.

    Omettere le parentesi

    Possiamo anche omettere le parentesi dopo new, se non ci sono argomenti:

    let user = new User; // <-- no parentheses
    // same as
    let user = new User();

    Lomissione delle parentesi non viene considerata come buona programmazione, la sintassi comunque lo permette.

    Metodi in un costruttore

    Utilizzare costruttori per creare degli oggetti ci d un grande vantaggio in termini di flessibilit. Il costruttore pu avere dei parametri che definiscono come costruire loggetto, e cosa metterci dentro.

    Ovviamente, possiamo aggiunger a this non solo propriet, ma anche metodi.

    Ad esempio, new User(name) crea un oggetto con un nome (passato come name) e un metodo sayHi:

    function User(name) {
      this.name = name;
    
      this.sayHi = function() {
        alert( "My name is: " + this.name );
      };
    }
    
    let john = new User("John");
    
    john.sayHi(); // My name is: John
    
    /*
    john = {
       name: "John",
       sayHi: function() { ... }
    }
    */

    Per creare oggetti pi complessi, esiste una sintassi pi avanzata, classes, che copriremo pi avanti.

    Riepilogo

    • Le funzioni di costruzione, o meglio, i costruttori, sono solo delle normali funzioni; seguono per una convenzione comune che prevede di denominarle con la prima lettera maiuscola.
    • Un costruttore dovrebbe essere chiamato solamente utilizzando new. Questo tipo di chiamata implica la creazione di un oggetto vuoto, this, che verr popolato entro la fine della funzione.

    Possiamo utilizzare i costruttori per costruire molti oggetti simili tra loro.

    JavaScript fornisce costruttori per la maggior parte degli oggetti integrati nel linguaggio: come Date per le date, Set per gli insiemi e molti altri che studieremo pi avanti.

    Oggetti, ci ritorneremo!

    In questo capitolo abbiamo coperto solamente le basi degli oggetti e dei costruttori. Era necessario conoscerne le basi per capire meglio i data types e le funzioni che studieremo nel prossimo capitolo.

    Dopo questo, ritorneremo sugli oggetti e li analizzeremo pi in dettaglio nei capitoli Prototypes, inheritance e Classi.

    Esercizi

    importanza: 2

    E possibile creare due funzioni A e B tali che new A()==new B()?

    function A() { ... }
    function B() { ... }
    
    let a = new A;
    let b = new B;
    
    alert( a == b ); // true

    Se pensi che sia possibile, prova a scrivere il codice.

    soluzione

    Si, possibile.

    Se una funzione ritorna un oggetto, questo verr ritornato da new invece di this.

    Quindi, le due funzioni potrebbero ritornare un oggetto definito esternamente obj:

    let obj = {};
    
    function A() { return obj; }
    function B() { return obj; }
    
    alert( new A() == new B() ); // true
    importanza: 5

    Scrivete un costruttore Calculator che crea oggetti con 3 metodi:

    • read() richiede due valori utilizzando prompt e li memorizza nelle propriet delloggetto.
    • sum() ritorna la somma delle propriet.
    • mul() ritorna il prodotto delle propriet.

    Ad esempio:

    let calculator = new Calculator();
    calculator.read();
    
    alert( "Sum=" + calculator.sum() );
    alert( "Mul=" + calculator.mul() );

    Esegui la demo

    Apri una sandbox con i test.

    soluzione
    function Calculator() {
    
      this.read = function() {
        this.a = +prompt('a?', 0);
        this.b = +prompt('b?', 0);
      };
    
      this.sum = function() {
        return this.a + this.b;
      };
    
      this.mul = function() {
        return this.a * this.b;
      };
    }
    
    let calculator = new Calculator();
    calculator.read();
    
    alert( "Sum=" + calculator.sum() );
    alert( "Mul=" + calculator.mul() );

    Apri la soluzione con i test in una sandbox.

    importanza: 5

    Scrivete un costruttore Accumulator(startingValue).

    Loggetto che viene creato dovrebbe:

    • Salvare il valore corrente nella propriet value. Il valore di partenza viene impostato prendendo il valore passato allargomentto del costruttore startingValue.
    • Il metodo read() dovrebbe richiedere tramite prompt un numero e sommarlo a value.

    In altre parole, la propriet value la somma di tutti i numeri inseriti dallutente partendo dal valore iniziale startingValue.

    Qui una demo del codice:

    let accumulator = new Accumulator(1); // initial value 1
    
    accumulator.read(); // adds the user-entered value
    accumulator.read(); // adds the user-entered value
    
    alert(accumulator.value); // shows the sum of these values

    Esegui la demo

    Apri una sandbox con i test.

    soluzione
    function Accumulator(startingValue) {
      this.value = startingValue;
    
      this.read = function() {
        this.value += +prompt('How much to add?', 0);
      };
    
    }
    
    let accumulator = new Accumulator(1);
    accumulator.read();
    accumulator.read();
    alert(accumulator.value);

    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