Klasy w JavaScript

Ten artykuł wyjaśnia klasy w JavaScript.

YouTube Video

Klasy w JavaScript

W JavaScript klasa wprowadza pojęcie programowania obiektowego i służy jako szablon dla obiektów. Dzięki klasom można w zwięzły sposób definiować właściwości i metody obiektu, co poprawia wielokrotność użycia kodu i jego organizację. Składnia klas została wprowadzona w JavaScript w wersji ES6.

Definicja Klasy

Klasa jest definiowana za pomocą słowa kluczowego class i zazwyczaj inicjalizowana metodą zwaną konstruktorem.

 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
  • Definiujemy klasę za pomocą class Person.
  • Constructor to specjalna metoda, która jest automatycznie wywoływana podczas tworzenia obiektu.
  • Słowo kluczowe this odnosi się do instancji (obiektu) klasy w obrębie klasy.

Właściwości i Metody Klasy

Klasa może definiować właściwości i metody. Właściwości reprezentują atrybuty obiektu, a metody reprezentują funkcje, które on posiada.

 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

W tym przykładzie deklarujemy klasę Car z właściwościami brand i model oraz metodą drive.

Dziedziczenie Klasy

Klasy mogą dziedziczyć po innych klasach. Dzięki dziedziczeniu można stworzyć nową klasę na podstawie istniejącej i dodać do niej dodatkową funkcjonalność.

 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

W tym przykładzie klasa Dog dziedziczy po klasie Animal.

  • Słowo kluczowe extends jest używane do dziedziczenia po klasie Animal.
  • W konstruktorze klasy Dog wykorzystuje się super(), aby wywołać konstruktor klasy nadrzędnej. Pozwala to na odziedziczenie procesu inicjalizacji z klasy nadrzędnej.
  • W odziedziczonej klasie można nadpisać metody klasy nadrzędnej. W tym przykładzie, zamiast "Rex wydaje odgłosy", wyświetla się "Rex szczeka".

Metody Statyczne

Kiedy definiujesz metodę statyczną w klasie, metoda ta jest związana z samą klasą. Metody statyczne mogą być wywoływane bez tworzenia instancji.

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

W tym przykładzie klasa MathUtils ma zdefiniowaną statyczną metodę add.

  • Słowo kluczowe static jest używane do definiowania metody statycznej.
  • Metody statyczne nie należą do instancji klasy i mogą być wywoływane bezpośrednio z samej klasy.

Akcesory (Gettery i Settery)

Definiując gettery i settery w klasie, możesz enkapsulować pobieranie i ustawianie właściwości.

 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

W tym przykładzie klasa Rectangle definiuje getter area i setter widthValue.

  • Getter (get) jest wywoływany podczas uzyskiwania wartości właściwości.
  • Setter (set) jest wywoływany podczas ustawiania wartości właściwości.

Składniowe Ułatwienia Klas (Syntactic Sugar)

W JavaScript składnia klas wewnętrznie opiera się na użyciu funkcji konstruktorów i prototypów. Składnia klas to składniowy cukier (syntactic sugar), który pozwala zapisać to w bardziej zwięzły sposób.

 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

W tym przykładzie została zdefiniowana funkcja konstruktor Person, a metoda greet jest zdefiniowana za pomocą prototypu.

Obsługa this

Słowo kluczowe this wewnątrz klasy odnosi się do instancji tej klasy. Jednak podczas pracy z this w metodach klasy należy pamiętać, że jego zachowanie może się różnić w zależności od zakresu. Problemy mogą wystąpić szczególnie podczas używania metod jako funkcji zwrotnych (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.

W takich przypadkach, gdy metoda jest przekazywana jako funkcja zwrotna do setTimeout, odniesienie this może ulec zmianie. Aby uniknąć tego problemu, zaleca się albo przypiąć this za pomocą metody bind, albo użyć funkcji strzałkowych.

 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);

Podsumowanie

  • Klasy są używane jako wzorce do tworzenia obiektów, definiowania właściwości i metod.
  • Możesz użyć dziedziczenia, aby rozszerzyć klasę, korzystając z koncepcji programowania obiektowego.
  • Metody statyczne należą do samej klasy i mogą być używane bez tworzenia instancji.
  • Możesz enkapsulować właściwości za pomocą getterów i setterów.
  • Składnia klasy w JavaScripcie to cukier składniowy i wewnętrznie używa dziedziczenia opartego na prototypach.

Korzystając z klas, możesz bardziej naturalnie obsługiwać programowanie obiektowe oraz poprawić możliwość ponownego użycia i utrzymania kodu.

Możesz śledzić ten artykuł, korzystając z Visual Studio Code na naszym kanale YouTube. Proszę również sprawdzić nasz kanał YouTube.

YouTube Video