Zajęcia

W projekcie ES6 wprowadzono koncepcję „klas” w języku JavaScript, która różni się od klas w innych językach programowania. Klasy to tu specjalne funkcje, które służą jako szablony do tworzenia obiektów, które już zawierają dane, właściwości powiązane z tymi danymi oraz metody związane z manipulacją tymi danymi. Te obiekty, właściwości i metody są zbiorczo nazywane „elementami” klasy.

Aby zdefiniować klasę, użyj słowa kluczowego class. Zgodnie ze sprawdzonymi metodami i konwencją ustaloną przez wbudowane funkcje konstruktora JavaScriptu każdy identyfikator klasy rozpocznij wielką literą:

class MyClass {}

Klasy mają na celu udostępnienie bardziej przystępnych sposobów pracy z zaawansowanymi funkcjami prototypów i funkcji konstruktorów:

class MyClass {}

typeof MyClass;
> "function"

Ponieważ dodaliśmy klasy, aby ułatwić i ułatwić pracę z zaawansowanymi funkcjami JavaScriptu, można je czasem nazywać „cukrem składniowym”. Zajęcia stanowią jednak coś więcej niż tylko przydatne narzędzie do pracy z dziedziczeniem prototypowym. Przedstawiamy możliwości tworzenia składni klas, które pozwalają rozwiązywać powtarzające się problemy z projektem w języku JavaScript bez wprowadzania problemów ze zgodnością wsteczną. Przykład: cały kod w treści klasy jest zawsze oceniany w trybie ścisłym.

Aby utworzyć instancję klasy, użyj operatora new.

class MyClass {}

const myClassInstance = new MyClass();

myClassInstance;
> Object { }

Funkcje zdefiniowane w treści klasy są wyświetlane jako metody w każdej instancji tej klasy.

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

const myClassInstance = new MyClass();

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

Metoda zdefiniowana w klasie staje się metodą na prototypie wynikowej instancji. Ze względu na charakter łańcucha prototypów możesz wywoływać te metody bezpośrednio w obiekcie wynikowym:

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."

Utworzenie instancji klasy wywołuje specjalną metodę constructor(), która wykonuje niezbędną „konfigurację” nowo utworzonej instancji i inicjuje powiązane z nią właściwości. Wszystkie argumenty przekazywane do klasy podczas tworzenia instancji są dostępne dla metody constructor():

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

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

Wartość this w treści klasy odnosi się do samej instancji, a wszelkie właściwości zdefiniowane w this są widoczne jako właściwości poszczególnych instancji tej klasy:

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

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

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

Te właściwości są też dostępne we wszystkich metodach w treści klasy:

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

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

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

Jeśli nie zdefiniujesz elementu constructor() dla swojej klasy, mechanizm JavaScript przyjmie, że pole „default” (constructor) jest puste. Każda klasa może mieć tylko 1 metodę specjalną o nazwie constructor():

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

Klasę możesz zdefiniować za pomocą deklaracji klasy lub wyrażenia klasy. Poprzednie przykłady to deklaracje klas, które wymagają wywołania nazw za pomocą funkcji new. Wyrażenia klas mogą być nazwane lub pozostawione bez nazwy, aby utworzyć klasę „anonimową”.

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

ClassExpression;
> class  {}

Jedną z rzeczy, których możesz używać z anonimowymi wyrażeniami klas, są funkcje, które tworzą klasy „na bieżąco”:

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

let MyVariable = classMaker();

MyVariable;
> class  {}

Ponowne zadeklarowanie klasy przy użyciu deklaracji klasy powoduje błąd składni:


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

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

Wyrażenia klas pozwalają jednak zmieniać definicję klasy:

let ClassExpression = class MyClass { };

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

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

Nie można wywołać nazwanego wyrażenia klasy według nazwy w taki sposób, jak robi się deklaracja klas. Dostępna jest jednak przypisana nazwa wyrażenia klasy jako właściwość utworzonej instancji, głównie po to, aby ułatwić debugowanie:

let MyVariable = class MyClass {};

MyClass;
> Uncaught ReferenceError: MyClass is not defined

MyVariable;
> class MyClass {}

MyVariable.name;
> "MyClass"

Gdy zainicjujesz zmienną za pomocą wyrażenia klasy, postępuj zgodnie z regułami podnoszenia tej zmiennej. Deklaracje klas są zgodne z tymi samymi regułami „tymczasowej strefy martwej” co w przypadku let i const. Deklaracje zachowują się tak, jakby nie zostały przeniesione na początek bieżącego zakresu. Oznacza to, że wywołanie klasy przed deklaracją klasy powoduje błąd:

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

    class MyClass {
        myProp;

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

Sprawdź swoją wiedzę

Która z poniższych opcji poprawnie definiuje klasę?

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

Ile metod constructor() może mieć klasa?

Jeden
Brak
Bez ograniczeń