Classi in JavaScript

Classi in JavaScript

Questo articolo spiega le classi in JavaScript.

YouTube Video

Classi in JavaScript

In JavaScript, una classe incorpora il concetto di programmazione orientata agli oggetti e funge da modello per gli oggetti. Con le classi, è possibile definire sinteticamente le proprietà e i metodi di un oggetto, migliorando la riusabilità e l'organizzazione del codice. La sintassi delle classi è stata introdotta in JavaScript con ES6.

Definizione della Classe

Una classe viene definita con la parola chiave class ed è in genere inizializzata con un metodo chiamato constructor.

 1class Person {
 2    // Constructor method (called when the class is instantiated)
 3    constructor(name, age) {
 4        this.name = name; // Property definition
 5        this.age = age;
 6    }
 7
 8    // Method definition
 9    greet() {
10        return `Hello, my name is ${this.name}`;
11    }
12}
13
14// Instantiation of the class
15const alice = new Person("Alice", 25);
16console.log(alice.greet()); // Hello, my name is Alice
  • Definiamo una classe con class Person.
  • Il constructor è un metodo speciale che viene chiamato automaticamente quando un oggetto viene creato.
  • La parola chiave this si riferisce all'istanza (oggetto) della classe all'interno della classe stessa.

Proprietà e Metodi della Classe

Una classe può definire proprietà e metodi. Le proprietà rappresentano gli attributi di un oggetto, e i metodi rappresentano le sue funzioni.

 1class Car {
 2    constructor(brand, model) {
 3        this.brand = brand;
 4        this.model = model;
 5    }
 6
 7    // Method definition
 8    drive() {
 9        console.log(`Driving a ${this.brand} ${this.model}`);
10    }
11}
12
13const car1 = new Car("Toyota", "Corolla");
14car1.drive(); // Driving a Toyota Corolla

In questo esempio, viene dichiarata una classe Car con le proprietà brand e model e un metodo drive.

Ereditarietà delle Classi

Le classi possono ereditare da altre classi. Utilizzando l'ereditarietà, è possibile creare una nuova classe basata su una classe esistente e aggiungere funzionalità aggiuntive.

 1class Animal {
 2    constructor(name) {
 3        this.name = name;
 4    }
 5
 6    speak() {
 7        console.log(`${this.name} makes a noise`);
 8    }
 9}
10
11// Inherit from the Animal class
12class Dog extends Animal {
13    constructor(name, breed) {
14        super(name); // Call the constructor of the parent class (Animal)
15        this.breed = breed;
16    }
17
18    // Override the method
19    speak() {
20        console.log(`${this.name} barks`);
21    }
22}
23
24const dog = new Dog("Rex", "German Shepherd");
25dog.speak(); // Rex barks

In questo esempio, la classe Dog eredita dalla classe Animal.

  • La parola chiave extends viene usata per ereditare dalla classe Animal.
  • Nel costruttore della classe Dog, super() viene utilizzato per chiamare il costruttore della classe genitore. Questo consente di ereditare il processo di inizializzazione della classe genitore.
  • All'interno della classe ereditata, è possibile sovrascrivere i metodi della classe genitore. In questo esempio, invece di "Rex emette un rumore", viene mostrato "Rex abbaia".

Metodi Statici

Quando si definisce un metodo statico all'interno di una classe, il metodo è associato alla classe stessa. I metodi statici possono essere chiamati senza essere istanziati.

1class MathUtils {
2    // Static method
3    static add(a, b) {
4        return a + b;
5    }
6}
7
8console.log(MathUtils.add(5, 10)); // 15

In questo esempio, la classe MathUtils ha definito un metodo statico add.

  • La parola chiave static viene utilizzata per definire un metodo statico.
  • I metodi statici non appartengono alle istanze della classe e possono essere chiamati direttamente dalla classe stessa.

Getter e Setter

Definendo getter e setter in una classe, è possibile incapsulare il recupero e l'impostazione delle proprietà.

 1class Rectangle {
 2    constructor(width, height) {
 3        this.width = width;
 4        this.height = height;
 5    }
 6
 7    // Getter
 8    get area() {
 9        return this.width * this.height;
10    }
11
12    // Setter
13    set widthValue(newWidth) {
14        this.width = newWidth;
15    }
16}
17
18const rect = new Rectangle(10, 20);
19console.log(rect.area); // 200
20
21rect.widthValue = 15;
22console.log(rect.area); // 300

In questo esempio, la classe Rectangle definisce un getter area e un setter widthValue.

  • Il getter (get) viene chiamato durante il recupero del valore di una proprietà.
  • Il setter (set) viene chiamato durante l'impostazione del valore di una proprietà.

Sintassi Zuccherata delle Classi

In JavaScript, la sintassi delle classi è implementata internamente utilizzando funzioni costruttore e prototipi. La sintassi delle classi è un syntactic sugar per scrivere queste strutture in modo più conciso.

 1// Example without using class syntax
 2function Person(name, age) {
 3    this.name = name;
 4    this.age = age;
 5}
 6
 7Person.prototype.greet = function() {
 8    return `Hello, my name is ${this.name}`;
 9};
10
11const person = new Person("Alice", 25);
12console.log(person.greet()); // Hello, my name is Alice

In questo esempio, è definita una funzione costruttore Person e il metodo greet è definito utilizzando un prototipo.

Gestione di this

La parola chiave this all'interno di una classe si riferisce all'istanza di quella classe. Tuttavia, durante l'uso di this nei metodi di classe, è necessario sapere che il suo comportamento può variare a seconda dello scope. I problemi possono sorgere in particolare quando si utilizzano metodi come funzioni di callback.

 1class Counter {
 2    constructor() {
 3        this.count = 0;
 4    }
 5
 6    increment() {
 7        this.count++;
 8        console.log(this.count);
 9    }
10}
11
12const counter = new Counter();
13setTimeout(counter.increment, 1000); // NaN
14// NaN, since this.count is undefined, it becomes NaN after incrementing.

In tali casi, quando viene passato come callback a setTimeout, il riferimento a this potrebbe cambiare. Per evitare questo problema, si consiglia di fissare this utilizzando il metodo bind o di utilizzare le funzioni freccia.

 1class Counter {
 2    constructor() {
 3        this.count = 0;
 4    }
 5
 6    increment() {
 7        this.count++;
 8        console.log(this.count);
 9    }
10}
11
12const counter = new Counter();
13
14// When using bind
15setTimeout(counter.increment.bind(counter), 1000);
16
17// When using an arrow function
18setTimeout(() => counter.increment(), 2000);

Riepilogo

  • Le classi vengono utilizzate come modelli per creare oggetti, definendo proprietà e metodi.
  • Puoi utilizzare l'ereditarietà per estendere una classe, sfruttando i concetti di programmazione orientata agli oggetti.
  • I metodi statici appartengono alla classe stessa e possono essere utilizzati senza creare un'istanza.
  • Puoi incapsulare le proprietà utilizzando getter e setter.
  • La sintassi delle classi in JavaScript è zucchero sintattico e utilizza internamente l'ereditarietà basata sui prototipi.

Utilizzando le classi, puoi gestire la programmazione orientata agli oggetti in modo più naturale e migliorare la riutilizzabilità e la manutenibilità del codice.

Puoi seguire l'articolo sopra utilizzando Visual Studio Code sul nostro canale YouTube. Controlla anche il nostro canale YouTube.

YouTube Video