w programowaniu obiektowym klasa jest rozszerzalnym szablonem program-kod-szablon do tworzenia obiektów, dostarczającym wartości początkowe dla stanu (zmiennych członkowskich) i implementacji zachowania (funkcji lub metod członkowskich).
w praktyce często musimy tworzyć wiele obiektów tego samego rodzaju, takich jak użytkownicy, towary lub cokolwiek innego.
Jak już wiemy z rozdziału Konstruktor, operator „new”,new function
może w tym pomóc.,
ale we współczesnym JavaScript, jest bardziej zaawansowana konstrukcja „class”, która wprowadza wspaniałe nowe funkcje, które są przydatne do programowania obiektowego.
składnia „class”
podstawowa składnia to:
class MyClass { // class methods constructor() { ... } method1() { ... } method2() { ... } method3() { ... } ...}
następnie użyjnew MyClass()
aby utworzyć nowy obiekt ze wszystkimi wymienionymi metodami.
constructor()
metoda jest wywoływana automatycznie przez new
, więc możemy tam zainicjalizować obiekt.,
na przykład:
class User { constructor(name) { this.name = name; } sayHi() { alert(this.name); }}// Usage:let user = new User("John");user.sayHi();
gdynew User("John")
jest wywołane:
- powstaje nowy obiekt.
-
constructor
uruchamia się z podanym argumentem i przypisuje go dothis.name
.
… wtedy możemy wywołać metody obiektowe, takie jak user.sayHi()
.
częstą pułapką dla początkujących programistów jest umieszczanie przecinków między metodami klasy, co spowodowałoby błąd składni.,
notacji nie należy mylić z literałami obiektowymi. W obrębie klasy nie są wymagane przecinki.
Co to jest klasa?
czym dokładnie jest class
? To nie jest zupełnie nowy byt na poziomie języka, jak można by pomyśleć.
odsłońmy każdą magię i zobaczmy czym naprawdę jest klasa. To pomoże w zrozumieniu wielu złożonych aspektów.
w JavaScript klasa jest rodzajem funkcji.,
spójrz tutaj:
class User { constructor(name) { this.name = name; } sayHi() { alert(this.name); }}// proof: User is a functionalert(typeof User); // function
co class User {...}
construct naprawdę robi:
- tworzy funkcję o nazwie
User
, która staje się wynikiem deklaracji klasy. Kod funkcji jest pobierany z metodyconstructor
(zakładana pusta, jeśli nie napiszemy takiej metody). - przechowuje metody klas, takie jak
sayHi
, wUser.prototype
.,
Ponew User
obiekt jest tworzony, kiedy wywołujemy jego metodę, jest pobierany z prototypu, tak jak opisano w rozdziale F. prototype. Obiekt ma więc dostęp do metod klasy.,z class User
deklaracja jako:
oto kod do introspekcji:
nie tylko cukier składniowy
czasami ludzie mówią, że class
jest „cukrem składniowym” (składnia, która ma na celu ułatwienie czytania, ale nie wprowadza niczego nowego), ponieważ moglibyśmy faktycznie zadeklarować to samo bez class
słowo kluczowe w ogóle:
wynik tej definicji jest mniej więcej taki sam., Istnieją więc powody, dla których class
można uznać za cukier składniowy do zdefiniowania konstruktora wraz z jego prototypowymi metodami.
mimo to istnieją istotne różnice.
-
najpierw funkcja utworzona przez
class
jest oznaczana specjalną wewnętrzną właściwością]:"classConstructor"
. Więc nie jest to całkowicie to samo, co tworzenie go ręcznie.język sprawdza tę właściwość w różnych miejscach., Na przykład, w przeciwieństwie do zwykłej funkcji, musi być wywołana za pomocą
new
:class User { constructor() {}}alert(typeof User); // functionUser(); // Error: Class constructor User cannot be invoked without 'new'
konstruktor klasy w większości silników JavaScript zaczyna się od „class…”
class User { constructor() {}}alert(User); // class User { ... }
są inne różnice, wkrótce je zobaczymy.
metody klas nie są wyliczalne.,Definicja klasy ustawia
enumerable
flagę nafalse
dla wszystkich metod w"prototype"
.to dobrze, ponieważ jeśli
for..in
nad obiektem, zwykle nie chcemy metod jego klasy.klasy zawsze
use strict
.Cały kod wewnątrz konstrukcji klasy jest automatycznie w trybie ścisłym.poza tym
class
składnia oferuje wiele innych funkcji, które poznamy później.,wyrażenie klasy
podobnie jak funkcje, klasy mogą być zdefiniowane wewnątrz innego wyrażenia, przekazywane, zwracane, przypisywane, itd.
oto przykład wyrażenia klasy:
let User = class { sayHi() { alert("Hello"); }};
podobnie do nazwanych wyrażeń funkcji, wyrażenia klas mogą mieć nazwę.,
jeśli wyrażenie klasy ma nazwę, jest widoczne tylko wewnątrz klasy:
możemy nawet tworzyć klasy dynamicznie „na żądanie”, jak to:
Getters/setters
podobnie jak dosłowne obiekty, klasy mogą zawierać getters / setters, właściwości obliczeniowe itp.
oto przykład
user.name
zaimplementowany przy użyciuget/set
:technicznie, taka deklaracja klas działa poprzez tworzenie getterów i setterów w
User.prototype
.,obliczone nazwy
oto przykład z nazwą metody obliczonej za pomocą nawiasów
:
class User { () { alert("Hello"); }}new User().sayHi();
takie funkcje są łatwe do zapamiętania, ponieważ przypominają obiekty dosłowne.
pola klasy
stare przeglądarki mogą potrzebować polyfillpola klasy są ostatnim dodatkiem do języka.
wcześniej Nasze klasy miały tylko metody.
„pola klas” to składnia pozwalająca na dodawanie dowolnych właściwości.,
na przykład dodajmy name
, na własność wclass User
s:class User { name = "John"; sayHi() { alert(`Hello, ${this.name}!`); }}new User().sayHi(); // Hello, John!
więc po prostu piszemy ” = ” w deklaracji i to wszystko.,
ważną różnicą pól klas jest to, że są one ustawiane na poszczególnych obiektach, a nie
User.prototype
:class User { name = "John";}let user = new User();alert(user.name); // Johnalert(User.prototype.name); // undefined
możemy również przypisywać wartości za pomocą bardziej złożonych wyrażeń i wywołań funkcji:
class User { name = prompt("Name, please?", "John");}let user = new User();alert(user.name); // John
tworzenie powiązanych metod z polami klas
jak pokazano w rozdziale Wiązanie funkcji funkcje w JavaScript mają dynamiczny
this
., To zależy od kontekstu rozmowy.więc jeśli metoda obiektu jest przekazywana i wywoływana w innym kontekście,
this
nie będzie już odniesieniem do jej obiektu.na przykład ten kod pokaże
undefined
:problem nazywa się”utrata
this
„.istnieją dwa podejścia do jej naprawiania, jak opisano w rozdziale powiązanie funkcji:
- przekazać funkcję owijającą, taką jak
setTimeout(() => button.click(), 1000)
. - powiązać metodę z obiektem, np. w konstruktorze.,
pola klasy zawierają inną, dość elegancką składnię:
pole klasy
click = () => {...}
jest tworzone na podstawie dla poszczególnych obiektów, dla każdegoButton
obiekt, zthis
wewnątrz niego odnosi się do tego obiektu. Możemy przekazaćbutton.click
w dowolnym miejscu, a wartośćthis
zawsze będzie poprawna.jest to szczególnie przydatne w środowisku przeglądarki, dla słuchaczy zdarzeń.,
podsumowanie
podstawowa składnia klasy wygląda następująco:
MyClass
jest technicznie funkcją (tą, którą dostarczamy jakoconstructor
), podczas gdy metody, gettery i settery są zapisywane doMyClass.prototype
.w kolejnych rozdziałach dowiemy się więcej o klasach, w tym dziedziczeniu i innych funkcjach.