Corsi

ES6 ha introdotto il concetto di "classi" in JavaScript, che differisce dalle classi di altri linguaggi di programmazione. Le classi sono funzioni speciali che servono da modelli per creare oggetti che contengono già dati, proprietà associate a questi dati e metodi relativi alla manipolazione di questi dati. Questi oggetti, proprietà e metodi sono collettivamente denominati "membri" della classe.

Per definire una classe, utilizza la parola chiave class. Seguendo le best practice e la convenzione stabilita dalle funzioni del costruttore integrate di JavaScript, inizia qualsiasi identificatore di una classe con una lettera maiuscola:

class MyClass {}

Le classi hanno lo scopo di fornire modi più accessibili per lavorare con le funzionalità avanzate di prototipi e funzioni del costruttore:

class MyClass {}

typeof MyClass;
> "function"

Poiché le classi sono state in parte aggiunte per rendere più semplice e accattivante l'utilizzo delle funzionalità JavaScript avanzate, vengono a volte definite "zuccheri sintattici". Tuttavia, le classi non si limitano a fornire utili comandi rapidi per lavorare con l'ereditarietà prototipale. L'introduzione della sintassi delle classi ha creato opportunità per risolvere problemi di progettazione di lunga data in JavaScript senza introdurre problemi di compatibilità con le versioni precedenti. Ad esempio, tutto il codice all'interno del corpo di una classe viene sempre valutato in modalità rigida.

Per creare un'istanza di una classe, utilizza l'operatore new.

class MyClass {}

const myClassInstance = new MyClass();

myClassInstance;
> Object { }

Le funzioni definite all'interno del corpo di una classe vengono mostrate come metodi per ogni istanza di quella classe.

class MyClass {
    classMethod() {
        console.log( "My class method." );
    }
}

const myClassInstance = new MyClass();

myClassInstance.classMethod();
> "My class method."

Un metodo definito all'interno di una classe diventa un metodo sul prototipo dell'istanza risultante. A causa della natura della catena di prototipi, puoi chiamare questi metodi direttamente sull'oggetto risultante:

class MyClass {
  classMethod() {
    console.log( "My class method." );
  }
}

const myClassInstance = new MyClass( "A string." );

myClassInstance;
> Object { }
    <prototype>: Object { … }
        classMethod: function classMethod()
        constructor: class MyClass { constructor(myPassedValue) }
        <prototype>: Object { … }

myClassInstance.classMethod();
> "My class method."

La creazione di un'istanza di una classe chiama un metodo constructor() speciale che esegue l'eventuale "configurazione" necessaria per l'istanza appena creata e inizializza tutte le proprietà associate. Qualsiasi argomento passato alla classe durante la creazione dell'istanza è disponibile per il metodo constructor():

class MyClass {
  constructor( myPassedValue ) {
    console.log( myPassedValue );
  }
}

const myClassInstance = new MyClass( "A string." );
> "A string."

Nel corpo di una classe, il valore di this si riferisce all'istanza stessa, con tutte le proprietà definite su this esposte come proprietà di ogni istanza di quella classe:

class MyClass {
  constructor( myPassedValue ) {
    this.instanceProperty = myPassedValue;
  }
}

const myClassInstance = new MyClass( "A string." );

myClassInstance;
> Object { instanceProperty: "A string." }

Queste proprietà sono disponibili anche per tutti i metodi nel corpo della classe:

class MyClass {
  constructor( myPassedValue ) {
    this.instanceProp = myPassedValue;
  }
  myMethod() {
    console.log( this.instanceProp );
  }
}

const myClassInstance = new MyClass( "A string." );

myClassInstance.myMethod();
> "A string."

Se non definisci un valore constructor() per la classe, il motore JavaScript presuppone un valore constructor "predefinito" vuoto. Ogni classe può avere un solo metodo speciale denominato constructor():

class MyClass {
  constructor() {}
  constructor() {}
}
> Uncaught SyntaxError: A class may only have one constructor

Puoi definire una classe utilizzando una dichiarazione di classe o un'espressione di classe. Gli esempi precedenti sono tutte dichiarazioni di classe, che richiedono di richiamare i nomi utilizzando new. Le espressioni di classe possono essere nominate o lasciate senza nome per creare una classe "anonima".

let ClassExpression = class {
    constructor() {}
};

ClassExpression;
> class  {}

Puoi usare espressioni di classe anonime per le funzioni che creano classi "al volo":

function classMaker() {
  return class {
    constructor() {}
  };
}

let MyVariable = classMaker();

MyVariable;
> class  {}

La nuova dichiarazione di una classe mediante una dichiarazione di classe causa un errore di sintassi:


class MyClass {
    constructor( ) {
        console.log( "My class." );
    }
};

class MyClass {
    constructor() {
        console.log( "My new class." );
    }
};
> Uncaught SyntaxError: redeclaration of class MyClass

Tuttavia, le espressioni di classe consentono di ridefinire una classe:

let ClassExpression = class MyClass { };

ClassExpression = class MyOtherClass {
    constructor( myString ) {
        this.myProp = myString;
    }
};

new ClassExpression( "String." );
> MyOtherClass {myProp: 'String.'}

Non puoi richiamare un'espressione di classe denominata per nome, come puoi fare con una dichiarazione di classe. Tuttavia, il nome assegnato di un'espressione di classe è disponibile come proprietà dell'istanza creata, principalmente per semplificare il debug:

let MyVariable = class MyClass {};

MyClass;
> Uncaught ReferenceError: MyClass is not defined

MyVariable;
> class MyClass {}

MyVariable.name;
> "MyClass"

Quando inizializza una variabile utilizzando un'espressione di classe, le regole di sollevamento di quella variabile vengono seguite come previsto. Le dichiarazioni di classe seguono le stesse regole di "zona morta temporale" di let e const e si comportano come se non fossero state issate in cima all'ambito attuale, ossia il richiamo di una classe prima che la dichiarazione di classe provochi un errore:

{
    let myVar = new MyClass( "Property string." );

    class MyClass {
        myProp;

        constructor( myString ) {
            this.myProp = myString;
        }
    };
};
> Uncaught ReferenceError: Cannot access 'MyClass' before initialization

Verifica le tue conoscenze

Quale delle seguenti affermazioni definisce correttamente una classe?

class MyClass {}
myClass = class {}
new class()

Quanti metodi constructor() può avere un corso?

Uno
Nessuno
Schermi illimitati