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?