From 074785cea106179cb3305637055ab0a009ca74f2 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:42:52 -0500 Subject: initial commit --- .../reference/classes/extends/index.html | 88 +++++ .../pl/web/javascript/reference/classes/index.html | 410 +++++++++++++++++++++ .../reference/classes/konstruktor/index.html | 188 ++++++++++ .../classes/private_class_fields/index.html | 205 +++++++++++ .../classes/public_class_fields/index.html | 269 ++++++++++++++ .../javascript/reference/classes/static/index.html | 138 +++++++ 6 files changed, 1298 insertions(+) create mode 100644 files/pl/web/javascript/reference/classes/extends/index.html create mode 100644 files/pl/web/javascript/reference/classes/index.html create mode 100644 files/pl/web/javascript/reference/classes/konstruktor/index.html create mode 100644 files/pl/web/javascript/reference/classes/private_class_fields/index.html create mode 100644 files/pl/web/javascript/reference/classes/public_class_fields/index.html create mode 100644 files/pl/web/javascript/reference/classes/static/index.html (limited to 'files/pl/web/javascript/reference/classes') diff --git a/files/pl/web/javascript/reference/classes/extends/index.html b/files/pl/web/javascript/reference/classes/extends/index.html new file mode 100644 index 0000000000..6b25a766e5 --- /dev/null +++ b/files/pl/web/javascript/reference/classes/extends/index.html @@ -0,0 +1,88 @@ +--- +title: extends +slug: Web/JavaScript/Reference/Classes/extends +tags: + - Classes + - ECMAScript 2015 + - JavaScript +translation_of: Web/JavaScript/Reference/Classes/extends +--- +
{{jsSidebar("Classes")}}
+ +

Słowo kluczowe extends jest używane w deklaracjach klas lub wyrażeniach class do tworzenia klasy jako elementu potomnego innej klasy.

+ +
{{EmbedInteractiveExample("pages/js/classes-extends.html")}}
+ + + +

Składnia

+ +
class ChildClass extends ParentClass { ... }
+ +

Opis

+ +

Słowo kluczowe extends może być użyte do dziedziczenia po niestandardowych klasach lub standardowych obiektach wbudowanych.

+ +

Prototypem rozszerzenia musi być {{jsxref("Object")}} lub {{jsxref("null")}}.

+ +

Przykłady

+ +

Zastosowanie extends

+ +

Pierwszy przykład tworzy klasę Square rozszerzającą klasę Polygon. live demo (source).

+ +
class Square extends Polygon {
+  constructor(length) {
+    // Wywołanie konstruktora klasy nadrzędnej
+    // określenie szerokości i wysokości wielokątu
+    super(length, length);
+    // Uwaga: W pochodnych klasach, super() musi być wywołane wcześniej niż
+    // pierwsze użycie 'this'. W przeciwnym wypadku pojawi się błąd odniesienia.
+    this.name = 'Square';
+  }
+
+  get area() {
+    return this.height * this.width;
+  }
+}
+ +

Zastosowanie extends z obiektami wbudowanymi

+ +

Poniższy przykład rozszerza wbudowany obiekt {{jsxref("Date")}}. live demo (source).

+ +
class myDate extends Date {
+
+  getFormattedDate() {
+    var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
+    return this.getDate() + '-' + months[this.getMonth()] + '-' + this.getFullYear();
+  }
+}
+
+ +

Specyfikacje

+ + + + + + + + + + +
Specyfikacja
{{SpecName('ESDraft', '#sec-class-definitions', 'extends')}}
+ +

Kompatybilność

+ + + +

{{Compat("javascript.classes.extends")}}

+ +

Zobacz też

+ + diff --git a/files/pl/web/javascript/reference/classes/index.html b/files/pl/web/javascript/reference/classes/index.html new file mode 100644 index 0000000000..81388acbc3 --- /dev/null +++ b/files/pl/web/javascript/reference/classes/index.html @@ -0,0 +1,410 @@ +--- +title: Classes +slug: Web/JavaScript/Reference/Classes +tags: + - Classes + - Constructors + - ECMAScript 2015 + - Inheritance + - Intermediate + - JavaScript + - TopicStub +translation_of: Web/JavaScript/Reference/Classes +--- +
{{JsSidebar("Classes")}}
+ +

Klasy w Javascript zostały wprowadzone w ECMAScript 2015 jako lukier składniowy (ang. syntactic sugar) dla istniejącego, opartego na prototypach modelu dziedziczenia. Składnia klas nie wprowadza nowego zorientowanego obiektowo modelu dziedziczenia. Klasy wprowadzają znacznie prostszą i bardziej czytelną składnię do tworzenia obiektów i dziedziczenia.

+ +

Definiowanie klas

+ +

Klasy są w zasadzie "szczególnymi funkcjami". Podobnie jak w funkcji można definiować wyrażenie function i deklaracje funkcji, tak składnia klasy posiada dwa komponenty: wyrażenie class i deklaracje klasy.

+ +

Deklaracje klas

+ +

Jednym ze sposobów definiowania klas jest deklaracja klasy. Aby zadeklarować klasę, należy użyć słowa kluczowego class wraz z nazwą klasy (w tym przypadku "Prostokat").

+ +
class Prostokat {
+  constructor(wysokosc, szerokosc) {
+    this.wysokosc = wysokosc;
+    this.szerokosc = szerokosc;
+  }
+}
+ +

Hoisting

+ +

Ważną różnicą pomiędzy deklaracją funkcji a deklaracją klasy jest to, że deklaracje funkcji są przenoszone na początek ({{Glossary("Hoisting")}}) a klas nie. Najpierw musisz zadeklarować swoją klasę, by mieć do niej dostęp, w przeciwnym razie kod, jak ten poniżej, wygeneruje błąd {{jsxref("ReferenceError")}}:

+ +
var p = new Prostokat(); // ReferenceError
+
+class Prostokat {}
+
+ +

Wyrażenie class

+ +

Wyrażenie class jest kolejnym sposobem definiowania klasy. Wyrażenia class mogą być nazwane lub nienazwane. Nazwa przypisana nazwanemu wyrażeniu class jest lokalna dla ciała klasy. (można ją odczytać z właściwości {{jsxref("Function.name", "name")}} klasy)

+ +
// nienazwane
+var Prostokat = class {
+  constructor(wysokosc, szerokosc) {
+    this.wysokosc = wysokosc;
+    this.szerokosc = szerokosc;
+  }
+};
+console.log(Prostokat.name); // Prostokat
+
+// nazwane
+var Prostokat = class Prostokat2 {
+  constructor(wysokosc, szerokosc) {
+    this.wysokosc = wysokosc;
+    this.szerokosc = szerokosc;
+  }
+};
+console.log(Prostokat.name); // Prostokat2
+
+ +
+

Uwaga: Wyrażenia class dotykają te same kwestie związane z przenoszeniem na początek (ang. hoisting) co wspomnianych deklaracji klas.

+
+ +

Ciało klasy i definicje metod

+ +

Ciało klasy jest umieszczane w nawiasach klamrowych {}. To tam definiuje się metody, czy konstruktory.

+ +

Tryb ścisły

+ +

Ciało klasy jest wykonywane w trybie ścisłym (ang. strict mode). W celu poprawienia wydajności, kod wykorzystywany tutaj podlega ścisłej składni; nie pozwala to na ukrycie niektórych wyjątków, a pewne słowa kluczowe są rezerwowane dla przyszłych wersji ECMAScript.

+ +

Konstruktor

+ +

Constructor jest szczególną metodą, która służy tworzeniu i inicjalizowaniu obiektu zdefiniowanego słowem kluczowym class. Dozwolony jest tylko jeden konstruktor w danej klasie. Jeśli klasa posiada więcej niż jedno wystąpienie metody constructor, wygenerowany zostanie błąd {{jsxref("SyntaxError")}}.

+ +

Aby wywołać konstruktor klasy bazowej, należy użyć słowa kluczowego super.

+ +

Metody

+ +

Zobacz też definiowanie metod.

+ +
class Prostokat {
+  constructor(wysokosc, szerokosc) {
+    this.wysokosc = wysokosc;
+    this.szerokosc = szerokosc;
+  }
+  // Getter
+  get pole() {
+    return this.liczPole();
+  }
+  // Method
+  liczPole() {
+    return this.wysokosc * this.szerokosc;
+  }
+}
+
+const kwadrat = new Prostokat(10, 10);
+
+console.log(kwadrat.pole); // 100
+ +

Metody i właściwości statyczne

+ +

Słowo kluczowe static definiuje metodę kub właściwość statyczną w klasie. Statyczne metody i właściwości są wywoływane bez inicjalizowania ich klas i nie mogą być wywołane przez instancję klasy.

+ +
class Punkt {
+  constructor(x, y) {
+    this.x = x;
+    this.y = y;
+  }
+
+  static nazwa = "Punkt";
+  static odleglosc(a, b) {
+    const dx = a.x - b.x;
+    const dy = a.y - b.y;
+
+    return Math.sqrt(dx*dx + dy*dy);
+  }
+}
+
+const p1 = new Punkt(5, 5);
+const p2 = new Punkt(10, 10);
+p1.nazwa; // undefined
+p1.odleglosc; // undefined
+p2.nazwa; // undefined
+p2.odleglosc; // undefined
+
+console.log(Punkt.nazwa); // "Punkt"
+console.log(Punkt.odleglosc(p1, p2)); // 7.0710678118654755
+ +

Powiązanie this z metodami niestatycznymi i statycznymi

+ +

Kiedy metoda typu static lub prototype jest wywoływana bez this (na przykład poprzez przypisanie metody do zmiennej), wtedy this będzie undefined w środku metody. Takie zachowanie będzie takie same, nawet jeżeli dyrektywa "use strict" nie będzie obecna, ponieważ kod w obrębie metody danej klasy zawsze będzie wykonywał się jako strict mode.

+ +
class Animal {
+  speak() {
+    return this;
+  }
+  static eat() {
+    return this;
+  }
+}
+
+let obj = new Animal();
+obj.speak(); // obiekt Animal
+let speak = obj.speak;
+speak(); // undefined
+
+Animal.eat(); // klasa Animal
+let eat = Animal.eat;
+eat(); // undefined
+ +

Jeśli przepiszemy powyższy przykład z użyciem tradycyjnych funkcji bez dyrektywy "use strict", to this wywołane w metodzie będzie automatycznie przypisane do pierwotnej wartości this, którą domyślnie jest global object.

+ +
function Animal() { }
+
+Animal.prototype.speak = function() {
+  return this;
+}
+
+Animal.eat = function() {
+  return this;
+}
+
+let obj = new Animal();
+let speak = obj.speak;
+speak(); // global object
+
+let eat = Animal.eat;
+eat(); // global object
+
+ +

Właściwości instancji

+ +

Właściwości instancji muszą być zdefiniowane wewnątrz metody klasy:

+ +
class Rectangle {
+  constructor(height, width) {
+    this.height = height;
+    this.width = width;
+  }
+}
+ +

Statyczne właściwości i właściwości prototypu muszą być zdefiniowane poza ciałem klasy:

+ +
Rectangle.staticWidth = 20;
+Rectangle.prototype.prototypeWidth = 25;
+ +

Deklaracje pól

+ +
+

Publiczna i prywatne deklaracje pól są funkcjonalnościami eksperymentalnymi zaproponowanymi na TC39. Wsparcie przeglądarek jest ograniczone, ale ta funkcjonalność może być używana przy użyciu systemów takich jak Babel

+
+ +

Deklaracje pól publicznych

+ +

Przy użyciu deklaracji pól, powyższy przykład może być przepisany na:

+ +
class Rectangle {
+  height = 0;
+  width;
+  constructor(height, width) {
+    this.height = height;
+    this.width = width;
+  }
+}
+
+ +

Dzięki deklarowaniu pól na początku klasy, definicje klas stają się bardziej samodokumentujące, a pola są zawsze obecne.

+ +

Jak widać w powyższym przykładzie, pola mogą być zadeklarowane z lub bez domyślnej wartości.

+ +

Zobacz public class fields po więcej informacji.

+ +

Deklaracje pól prywatnych

+ +

Używając deklaracji pól prywatnych, definicja może być zapisana w taki sposób:

+ +
class Rectangle {
+  #height = 0;
+  #width;
+  constructor(height, width) {
+    this.#height = height;
+    this.#width = width;
+  }
+}
+
+ +

Próba odniesienia się do prywatnego pola poza ciałem klasy wygeneruje błąd. Prywatne pola mogą być tylko odczytywane i modyfikowane wewnątrz ciała klasy. Poprzez definicję właściwości niewidocznych poza ciałem klasy, można zapewnić, że użytkownicy klasy nie będą polegali na jej wewnętrznych właściwościach.

+ +
+

Pola prywatne mogą być tylko zadeklarowane na początku ciała klasy

+
+ +

Prywatnych pól nie da się utworzyć później, poprzez przypisywanie, tak jak normalnych właściwości.

+ +

Po więcej informacji zobacz private class fields.

+ +

Podklasy z extends

+ +

Słowo kluczowe extends jest używane w deklaracjach klas lub wyrażeniach klas do tworzenia klasy jako elementu potomnego innej klasy.

+ +
class Animal {
+  constructor(name) {
+    this.name = name;
+  }
+
+  speak() {
+    console.log(this.name + ' makes a noise.');
+  }
+}
+
+class Dog extends Animal {
+  constructor(name) {
+    super(name); // wywyłanie konstruktora klasy nadrzędnej poprzez użycie super()
+  }
+  speak() {
+    console.log(this.name + ' barks.');
+  }
+}
+
+let d = new Dog('Mitzie');
+d.speak(); // Mitzie barks.
+
+ +

Jeśli w podklasie znajduje się konstruktor, musi najpierw wywołać super() przed użyciem "this".

+ +

Można również rozszerzyć tradycyjne klasy oparte na funkcjach:

+ +
function Animal (name) {
+  this.name = name;
+}
+
+Animal.prototype.speak = function () {
+  console.log(this.name + ' makes a noise.');
+}
+
+class Dog extends Animal {
+  speak() {
+    console.log(this.name + ' barks.');
+  }
+}
+
+let d = new Dog('Mitzie');
+d.speak(); // Mitzie barks
+
+ +

Zwróć uwagę, że klasy nie mogą rozszerzać zwykłych (niezdatnych do konstrukcji) obiektów. Jeśli chcesz dziedziczyć po zwykłym obiekcie, możesz, zamiast tego użyć {{jsxref ("Object.setPrototypeOf()")}}:

+ +
var Animal = {
+  speak() {
+    console.log(this.name + ' makes a noise.');
+  }
+};
+
+class Dog {
+  constructor(name) {
+    this.name = name;
+  }
+}
+
+Object.setPrototypeOf(Dog.prototype, Animal);// If you do not do this you will get a TypeError when you invoke speak
+
+let d = new Dog('Mitzie');
+d.speak(); //Mitzie makes a noise.
+
+ +

Species

+ +

Jeśli chcesz zwrócić obiekt {{jsxref("Array")}} w twojej klasie MyArray, która dziedziczy po Array, to możesz użyć wzorca "species", który pozwala na nadpisywanie domyślnych konstruktorów.

+ +

Na przykład, wywołanie metody {{jsxref("Array.map", "map()")}} zwraca domyślny konstruktor MyArray. Użycie {{jsxref("Symbol.species")}} pozwala na nadpisanie tego zachowania tak, by zwracany był obiekt typu Array, a nie MyArray:

+ +
class MyArray extends Array {
+  // Nadpisanie domyślnego kontruktora
+  static get [Symbol.species]() { return Array; }
+}
+
+var a = new MyArray(1,2,3);
+var mapped = a.map(x => x * x);
+
+console.log(mapped instanceof MyArray); // false
+console.log(mapped instanceof Array);   // true
+
+ +

Słowo kluczowe super

+ +

Słowo kluczowe super jest wykorzystywane do udostępniania i korzystania z funkcji klasy, po której nasz obiekt dziedziczy.

+ +
class Cat {
+  constructor(name) {
+    this.name = name;
+  }
+
+  speak() {
+    console.log(`${this.name} makes a noise.`);
+  }
+}
+
+class Lion extends Cat {
+  speak() {
+    super.speak();
+    console.log(`${this.name} roars.`);
+  }
+}
+
+let l = new Lion('Fuzzy');
+l.speak();
+// Fuzzy makes a noise.
+// Fuzzy roars.
+ +

Mix-ins

+ +

Abstrakcyjne podklasy lub mix-ins są szablonami dla klas. Klasa może mieć tylko jedną klasę nadrzędną, więc dziedziczenie z wielu klas jest niemożliwe. Cała funkcjonalność musi być dostarczona przez jedną klasę nadrzędną.

+ +

Funkcja przyjmująca klasę nadrzędną jako argument i zwracająca podklasę rozszerzającą klasę nadrzędną może być użyta do implementacji mix-in'ów:

+ +
var calculatorMixin = Base => class extends Base {
+  calc() { }
+};
+
+var randomizerMixin = Base => class extends Base {
+  randomize() { }
+};
+
+ +

Klasa używająca tych mix-in'ów może być zapisana w taki sposób:

+ +
class Foo { }
+class Bar extends calculatorMixin(randomizerMixin(Foo)) { }
+ +

Specyfikacje

+ + + + + + + + + + + + + + + + + + + +
SpecyfikacjaStatusKomentarz
{{SpecName('ES2015', '#sec-class-definitions', 'Class definitions')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-class-definitions', 'Class definitions')}}{{Spec2('ESDraft')}}
+ +

Kompatybilność

+ +

{{Compat("javascript.classes")}}

+ +

Zobacz też

+ + diff --git a/files/pl/web/javascript/reference/classes/konstruktor/index.html b/files/pl/web/javascript/reference/classes/konstruktor/index.html new file mode 100644 index 0000000000..353adecd19 --- /dev/null +++ b/files/pl/web/javascript/reference/classes/konstruktor/index.html @@ -0,0 +1,188 @@ +--- +title: Konstruktor +slug: Web/JavaScript/Reference/Classes/Konstruktor +tags: + - Classes + - JavaScript + - Language feature +translation_of: Web/JavaScript/Reference/Classes/constructor +--- +
{{jsSidebar("Classes")}}
+ +

Konstruktor jest specjalną metodą tworzenia i inicjowania obiektu utworzonego w klasie.

+ +

{{EmbedInteractiveExample("pages/js/classes-constructor.html")}}

+ +

Składnia

+ +
constructor([arguments]) { ... }
+ +

Opis

+ +

Konstruktor umożliwia zdefiniowanie inicjalizacji obiektu, która musi się wykonać, zanim będzie można wywołać metody obiektu.

+ +
class Person {
+
+  constructor(name) {
+    this.name = name;
+  }
+
+  introduce() {
+    console.log(`Hello, my name is ${this.name}`);
+  }
+
+}
+
+const otto = new Person('Otto');
+
+otto.introduce();
+ +

Jeśli niestandardowy konstruktor nie został podany, to domyślny konstruktor będzie użyty. Dla klas bazowych konstruktor domyślny jest pusty:

+ +
constructor() {}
+ +

Dla klas pochodnych domyślny konstruktor wywołuje konstruktor klasy nadrzędnej:

+ +
constructor(...args) {
+  super(...args);
+}
+ +

Pozwala to na działanie takiego kodu:

+ +
class ValidationError extends Error {
+
+  printCustomerMessage() {
+    return `Validation failed :-( (details: ${this.message})`;
+  }
+
+}
+
+try {
+  throw new ValidationError("Not a valid phone number");
+} catch (error) {
+   if (error instanceof ValidationError) {
+    console.log(error.name); // This is Error instead of ValidationError!
+    console.log(error.printCustomerMessage());
+  } else {
+    console.log('Unknown error', error);
+    throw error;
+  }
+}
+ +

Klasa ValidationError nie musi mieć niestandardowego konstruktora, ponieważ domyślny konstruktor wywołuje konstruktor klasy Error.

+ +

Jeśli jednak klasa ValidationError ma niestandardowy konstruktor, to musi on wywoływać konstruktor klasy nadrzędnej przy użyciu super:

+ +
class ValidationError extends Error {
+
+  constructor(message) {
+    super(message);  // call parent class constructor
+    this.name = 'ValidationError';
+    this.code = '42';
+  }
+
+  printCustomerMessage() {
+     return `Validation failed :-( (details: ${this.message}, code: ${this.code})`;
+  }
+
+}
+
+try {
+  throw new ValidationError("Not a valid phone number");
+} catch (error) {
+   if (error instanceof ValidationError) {
+    console.log(error.name); // Now this is ValidationError!
+    console.log(error.printCustomerMessage());
+  } else {
+    console.log('Unknown error', error);
+    throw error;
+  }
+}
+ +

Wewnątrz klasy może być tylko jedna metoda nazwana constructor. Jeżeli constructor wystąpi więcej niż jeden raz, to wygeneruje błąd {{jsxref("SyntaxError")}}.

+ +

Przykłady

+ +

Używanie konstruktora

+ +

Fragment kodu pochodzi z classes sample (live demo).

+ +
class Square extends Polygon {
+  constructor(length) {
+    // Wywołanie konstruktora klasy nadrzędnej
+    // określenie szerokości i wysokości wielokątu
+    super(length, length);
+    // Uwaga: W pochodnych klasach, super() musi być wywołane wcześniej niż
+    // pierwsze użycie 'this'. W przeciwnym wypadku pojawi się błąd odniesienia.
+    this.name = 'Square';
+  }
+
+  get area() {
+    return this.height * this.width;
+  }
+
+  set area(value) {
+    this.area = value;
+  }
+}
+ +

Inny przykład

+ +

W tym przykładzie klasa Square jest zmieniona — ale konstruktor klasy Polygon nadal jest wywoływany przy tworzeniu nowej instancji klasy Square.

+ +
class Polygon {
+    constructor() {
+        this.name = "Polygon";
+    }
+}
+
+class Square extends Polygon {
+    constructor() {
+        super();
+    }
+}
+
+class Rectangle {}
+
+Object.setPrototypeOf(Square.prototype, Rectangle.prototype);
+
+console.log(Object.getPrototypeOf(Square.prototype) === Polygon.prototype); //false
+console.log(Object.getPrototypeOf(Square.prototype) === Rectangle.prototype); //true
+
+let newInstance = new Square();
+console.log(newInstance.name); //Polygon
+ +

Specyfikacje

+ + + + + + + + + + + + + + + + + + + +
SpecyfikacjaStatusKomentarz
{{SpecName('ES2015', '#sec-static-semantics-constructormethod', 'Constructor Method')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-static-semantics-constructormethod', 'Constructor Method')}}{{Spec2('ESDraft')}}
+ +

Kompatybilność

+ +

{{Compat("javascript.classes.constructor")}}

+ +

Zobacz też

+ + diff --git a/files/pl/web/javascript/reference/classes/private_class_fields/index.html b/files/pl/web/javascript/reference/classes/private_class_fields/index.html new file mode 100644 index 0000000000..6b55474d5b --- /dev/null +++ b/files/pl/web/javascript/reference/classes/private_class_fields/index.html @@ -0,0 +1,205 @@ +--- +title: Private class fields +slug: Web/JavaScript/Reference/Classes/Private_class_fields +tags: + - Classes + - JavaScript + - Language feature +translation_of: Web/JavaScript/Reference/Classes/Private_class_fields +--- +
{{JsSidebar("Classes")}}
+ +

Właściwości klas są domyślnie publiczne i mogą być wywoływane i modyfikowane poza klasą. Istnieje jednak funkcjonalność eksperymentalna pozwalająca na zdefiniowanie pól prywatnych klasy przy użyciu # przed nazwą pola.

+ +

Składnia

+ +
class ClassWithPrivateField {
+  #privateField
+}
+
+class ClassWithPrivateMethod {
+  #privateMethod() {
+    return 'hello world'
+  }
+}
+
+class ClassWithPrivateStaticField {
+  static #PRIVATE_STATIC_FIELD
+}
+
+ +

Przykłady

+ +

Prywatne pola statyczne

+ +

Pola prywatne są dostępne z poziomu konstruktora klasy ze środka ciała klasy.

+ +

Prywatne pola statyczne są tylko dostępne z poziomu statycznych metod. 

+ +
class ClassWithPrivateStaticField {
+  static #PRIVATE_STATIC_FIELD
+
+  static publicStaticMethod() {
+    ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD = 42
+    return ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD
+  }
+}
+
+console.assert(ClassWithPrivateStaticField.publicStaticMethod() === 42)
+ +

Prywatne pola statyczne są dodawane do konstruktora klasy podczas wykonywania klasy.

+ +

Tylko klasa, która definiuje prywatne pola statyczne, może mieć do nich dostęp.

+ +

Może to prowadzić to nieoczekiwanego zachowania podczas używania this.

+ +
class BaseClassWithPrivateStaticField {
+  static #PRIVATE_STATIC_FIELD
+
+  static basePublicStaticMethod() {
+    this.#PRIVATE_STATIC_FIELD = 42
+    return this.#PRIVATE_STATIC_FIELD
+  }
+}
+
+class SubClass extends BaseClassWithPrivateStaticField { }
+
+let error = null
+
+try {
+  SubClass.basePublicStaticMethod()
+} catch(e) { error = e}
+
+console.assert(error instanceof TypeError)
+
+ +

Prywatne pola instancji

+ +

Prywatne pola instancji są deklarowane przy użyciu # names ("hash names"), czyli nazw poprzedzonych #. Znak # jest częścią nazwy. Jest używany do deklaracji i dostępu do właściwości.

+ +

Enkapsulacja jest wymuszona przez język. Próba dostępu do prywatnego pola poza klasą wygeneruje błąd Syntax Error.

+ +
class ClassWithPrivateField {
+  #privateField
+
+  constructor() {
+    this.#privateField = 42
+    this.#randomField = 444 // Syntax error
+  }
+}
+
+const instance = new ClassWithPrivateField()
+instance.#privateField === 42 // Syntax error
+
+ +

Prywatne metody

+ +

Prywatne metody statyczne

+ +

Podobnie jak ich publiczne odpowiedniki, prywatne metody statyczne są wywoływane przez samą klasę, a nie jej instancje. Podobnie jak pola prywatne, są dostępne tylko z poziomu ciała klasy.

+ +
class ClassWithPrivateStaticMethod {
+    static #privateStaticMethod() {
+        return 42
+    }
+
+    static publicStaticMethod1() {
+        return ClassWithPrivateStaticMethod.#privateStaticMethod();
+    }
+
+    static publicStaticMethod2() {
+        return this.#privateStaticMethod();
+    }
+}
+
+console.assert(ClassWithPrivateStaticMethod.publicStaticMethod1() === 42);
+console.assert(ClassWithPrivateStaticMethod.publicStaticMethod2() === 42);
+
+ +

Może to prowadzić do nieoczekiwanego zachowania przy używaniu this. W poniższym przykładzie this odnosi się do klasy Derived (a nie klasy Base) podczas wywołania metody Derived.publicStaticMethod2(), co powoduje błąd.

+ +
class Base {
+    static #privateStaticMethod() {
+        return 42;
+    }
+    static publicStaticMethod1() {
+        return Base.#privateStaticMethod();
+    }
+    static publicStaticMethod2() {
+        return this.#privateStaticMethod();
+    }
+}
+
+class Derived extends Base {}
+
+console.log(Derived.publicStaticMethod1()); // 42
+console.log(Derived.publicStaticMethod2()); // TypeError
+
+ +

Prywatne metody instancji

+ +

Prywatne metody instancji to metody dostępne dla instancji klasy, które mają podobne ograniczenia co prywatne pola instancji.

+ +
class ClassWithPrivateMethod {
+  #privateMethod() {
+    return 'hello world'
+  }
+
+  getPrivateMessage() {
+      return this.#privateMethod()
+  }
+}
+
+const instance = new ClassWithPrivateMethod()
+console.log(instance.getPrivateMessage())
+// expected output: "hello worl​d"
+ +

Prywatne metody mogą używać async lub być generatorami. Możliwe jest również tworzenie prywatnych getter'ów i setter'ów:

+ +
class ClassWithPrivateAccessor {
+  #message
+
+  get #decoratedMessage() {
+    return `✨${this.#message}✨`
+  }
+  set #decoratedMessage(msg) {
+    this.#message = msg
+  }
+
+  constructor() {
+    this.#decoratedMessage = 'hello world'
+    console.log(this.#decoratedMessage)
+  }
+}
+
+new ClassWithPrivateAccessor();
+// expected output: "✨hello worl​d✨"
+
+ +

Specyfikacje

+ + + + + + + + + + + + +
Specyfikacja
{{SpecName('Public and private instance fields', '#prod-FieldDefinition', 'FieldDefinition')}}
+ +

Kompatybilność

+ + + +

{{Compat("javascript.classes.private_class_fields")}}

+ +

Zobacz też

+ + diff --git a/files/pl/web/javascript/reference/classes/public_class_fields/index.html b/files/pl/web/javascript/reference/classes/public_class_fields/index.html new file mode 100644 index 0000000000..780300e64f --- /dev/null +++ b/files/pl/web/javascript/reference/classes/public_class_fields/index.html @@ -0,0 +1,269 @@ +--- +title: Public class fields +slug: Web/JavaScript/Reference/Classes/Public_class_fields +tags: + - Classes + - JavaScript + - Language feature +translation_of: Web/JavaScript/Reference/Classes/Public_class_fields +--- +
{{JsSidebar("Classes")}}
+ +
+
+

Ta strona opisuje funkcjonalności eksperymentalne

+ +

Deklaracje pól publicznych i prywatnych są funkcjonalnościami eksperymentalnymi (stage 3) zaproponowanymi na TC39.

+ +

Wsparcie przeglądarek jest ograniczone, ale ta funkcjonalność może być używana przy użyciu systemów takich jak Babel. Zobacz tabelę kompatybilności poniżej.

+
+
+ +

Zarówno statyczne, jak i instancyjne pola publiczne są właściwościami zapisywalnymi, wyliczalnymi i konfigurowalnymi. W przeciwieństwie do ich prywatnych odpowiedników uczestniczą w dziedziczeniu prototypów.

+ +

Składnia

+ +
class ClassWithInstanceField {
+  instanceField = 'instance field'
+}
+
+class ClassWithStaticField {
+  static staticField = 'static field'
+}
+
+class ClassWithPublicInstanceMethod {
+  publicMethod() {
+    return 'hello world'
+  }
+}
+
+ +

Przykłady

+ +

Publiczne pola statyczne

+ +

Publiczne pola statyczne są użyteczne, gdy chcesz, aby pole istniało tylko raz dla danej klasy, a nie dla każdej tworzonej instancji klasy. Jest to użyteczne w przypadku cache'ów, stałej konfiguracji lub innych danych, które nie muszą być replikowane na wszystkich instancjach.

+ +

Publiczne pola statyczne są deklarowane z użyciem słowa kluczowego static. Są dodawane do konstruktora klasy podczas jej wykonywania z użyciem {{jsxref("Global_Objects/Object/defineProperty", "Object.defineProperty()")}}. Są one dostępne z poziomu konstruktora klasy.

+ +
class ClassWithStaticField {
+  static staticField = 'static field'
+}
+
+console.log(ClassWithStaticField.staticField)
+// expected output: "static field"​
+
+ +

Pola bez inicjalizatorów są ustawiane na undefined.

+ +
class ClassWithStaticField {
+  static staticField
+}
+
+console.assert(ClassWithStaticField.hasOwnProperty('staticField'))
+console.log(ClassWithStaticField.staticField)
+// expected output: "undefined"
+ +

Publiczne pola statyczne nie są inicjalizowane ponownie w podklasach, ale można uzyskać do nich dostęp przez łańcuch prototypów.

+ +
class ClassWithStaticField {
+  static baseStaticField = 'base field'
+}
+
+class SubClassWithStaticField extends ClassWithStaticField {
+  static subStaticField = 'sub class field'
+}
+
+console.log(SubClassWithStaticField.subStaticField)
+// expected output: "sub class field"
+
+console.log(SubClassWithStaticField.baseStaticField)
+// expected output: "base field"
+ +

Przy inicjalizacji pól, this odnosi się do konstruktora klasy. Można się również odwołać przez nazwę i użyć super do otrzymania konstruktora klasy nadrzędnej (jeżeli istnieje).

+ +
class ClassWithStaticField {
+  static baseStaticField = 'base static field'
+  static anotherBaseStaticField = this.baseStaticField
+
+  static baseStaticMethod() { return 'base static method output' }
+}
+
+class SubClassWithStaticField extends ClassWithStaticField {
+  static subStaticField = super.baseStaticMethod()
+}
+
+console.log(ClassWithStaticField.anotherBaseStaticField)
+// expected output: "base static field"
+
+console.log(SubClassWithStaticField.subStaticField)
+// expected output: "base static method output"
+
+ +

Publiczne pola instancyjne

+ +

Publiczne pola instancyjne istnieją na każdej utworzonej instancji danej klasy. Poprzez zadeklarowanie pola publicznego, można zapewnić, że pole jest zawsze obecne, a definicja klasy jest bardziej samodokumentująca.

+ +

Publiczne pola instancyjne są dodawane przy użyciu {{jsxref("Global_Objects/Object/defineProperty", "Object.defineProperty()")}} podczas wykonywania konstruktora klasy, lub po wywołaniu metody super().

+ +
class ClassWithInstanceField {
+  instanceField = 'instance field'
+}
+
+const instance = new ClassWithInstanceField()
+console.log(instance.instanceField)
+// expected output: "instance field"
+ +

Pola bez inicjalizatorów są ustawiane na undefined.

+ +
class ClassWithInstanceField {
+  instanceField
+}
+
+const instance = new ClassWithInstanceField()
+console.assert(instance.hasOwnProperty('instanceField'))
+console.log(instance.instanceField)
+// expected output: "undefined"
+ +

Podobnie jak właściwości, nazwy pól mogą być obliczane.

+ +
const PREFIX = 'prefix'
+
+class ClassWithComputedFieldName {
+    [`${PREFIX}Field`] = 'prefixed field'
+}
+
+const instance = new ClassWithComputedFieldName()
+console.log(instance.prefixField)
+// expected output: "prefixed field"
+ +

Przy inicjalizacji pól this odnosi się do instancji klasy. Tak jak w publicznych metodach instancji, można odnieść się do klasy nadrzędnej, używając super.

+ +
class ClassWithInstanceField {
+  baseInstanceField = 'base field'
+  anotherBaseInstanceField = this.baseInstanceField
+  baseInstanceMethod() { return 'base method output' }
+}
+
+class SubClassWithInstanceField extends ClassWithInstanceField {
+  subInstanceField = super.baseInstanceMethod()
+}
+
+const base = new ClassWithInstanceField()
+const sub = new SubClassWithInstanceField()
+
+console.log(base.anotherBaseInstanceField)
+// expected output: "base field"
+
+console.log(sub.subInstanceField)
+// expected output: "base method output"
+ +

Publiczne metody

+ +

Publiczne metody statyczne

+ +

Słowo kluczowe static definiuje metodę statyczną dla klasy. Metody statyczne nie są wywoływane na instancjach klasy, ale na samej klasie. Są to często funkcje użytkowe, takie jak funkcje tworzenia lub klonowania obiektów.

+ +
class ClassWithStaticMethod {
+  static staticMethod() {
+    return 'static method has been called.';
+  }
+}
+
+console.log(ClassWithStaticMethod.staticMethod());
+// expected output: "static method has been called."
+ +

Metody statyczne są dodawane do konstruktora klasy z użyciem {{jsxref("Global_Objects/Object/defineProperty", "Object.defineProperty()")}} podczas wykonania klasy. Te metody są zapisywalne, niewyliczalne i konfigurowalne.

+ +

Publiczne metody instancyjne

+ +

Jak nazwa wskazuje, publiczne metody instancji to metody dostępne na instancjach klasy.

+ +
class ClassWithPublicInstanceMethod {
+  publicMethod() {
+    return 'hello world'
+  }
+}
+
+const instance = new ClassWithPublicInstanceMethod()
+console.log(instance.publicMethod())
+// expected output: "hello worl​d"
+ +

Publiczne metody instancji są dodawane do prototypu klasy z użyciem {{jsxref("Global_Objects/Object/defineProperty", "Object.defineProperty()")}} podczas wykonania klasy. Te metody są zapisywalne, niewyliczalne i konfigurowalne.

+ +

Publiczne metody mogą używać async lub być generatorami.

+ +
class ClassWithFancyMethods {
+  *generatorMethod() { }
+  async asyncMethod() { }
+  async *asyncGeneratorMethod() { }
+}
+ +

Wewnątrz metod instancji, this odnosi się do samej instancji. W podklasach można użyć super do dostępu do prototypu klasy nadrzędnej, umożliwiając wywoływanie metod tej klasy.

+ +
class BaseClass {
+  msg = 'hello world'
+  basePublicMethod() {
+    return this.msg
+  }
+}
+
+class SubClass extends BaseClass {
+  subPublicMethod() {
+    return super.basePublicMethod()
+  }
+}
+
+const instance = new SubClass()
+console.log(instance.subPublicMethod())
+// expected output: "hello worl​d"
+
+ +

Getter'y i setter'y to specjalne metody, które wiążą się z właściwością danej klasy i są wywoływane, gdy właściwość jest odczytywana lub modyfikowana. Do tworzenia getter'ów i setter'ów należy użyć get and set.

+ +
class ClassWithGetSet {
+  #msg = 'hello world'
+  get msg() {
+    return this.#msg
+  }
+  set msg(x) {
+    this.#msg = `hello ${x}`
+  }
+}
+
+const instance = new ClassWithGetSet()
+console.log(instance.msg)
+// expected output: "hello worl​d"
+
+instance.msg = 'cake'
+console.log(instance.msg)
+// expected output: "hello cake"
+
+ +

Specyfikacje

+ + + + + + + + + + + + +
Specyfikacja
{{SpecName('Public and private instance fields', '#prod-FieldDefinition', 'FieldDefinition')}}
+ +

Kompatybilność

+ + + +

{{Compat("javascript.classes.public_class_fields")}}

+ +

Zobacz też

+ + diff --git a/files/pl/web/javascript/reference/classes/static/index.html b/files/pl/web/javascript/reference/classes/static/index.html new file mode 100644 index 0000000000..814c118957 --- /dev/null +++ b/files/pl/web/javascript/reference/classes/static/index.html @@ -0,0 +1,138 @@ +--- +title: static +slug: Web/JavaScript/Reference/Classes/static +tags: + - Classes + - ECMAScript 2015 + - JavaScript + - Static +translation_of: Web/JavaScript/Reference/Classes/static +--- +
{{jsSidebar("Classes")}}
+ +

Słowo kluczowe static definiuje statyczną metodę lub właściwość klasy. Metody i właściwości statyczne nie są wywoływane na instancjach klasy, a bezpośrednio na samej klasie. Statyczne metody to często funkcje służące na przykład do tworzenia czy klonowania obiektów, a statyczne właściwości są użyteczne do cache'ów, stałej konfiguracji lub innych właściwości, które nie muszą być powielane w instancjach.

+ +
{{EmbedInteractiveExample("pages/js/classes-static.html")}}
+ + + +

Składnia

+ +
static nazwaMetody() { ... }
+static nazwaWlasciwosci [=wartosc];
+
+ +

Przykłady

+ +

Używanie static w klasach

+ +

Poniższy przykład demonstruje kilka rzeczy:

+ +
    +
  1. Jak statyczna metoda lub właściwość jest implementowana w klasie
  2. +
  3. Klasa z metodą lub właściwością statyczną może być dziedziczona
  4. +
  5. Jak metoda lub właściwość statyczna może być wywoływana
  6. +
+ +
class Triple {
+  static customName = 'Tripler';
+  static description = 'I triple any number you provide';
+  static triple(n = 1) {
+    return n * 3;
+  }
+}
+
+class BiggerTriple extends Triple {
+  static longDescription;
+  static description = 'I square the triple of any number you provide';
+  static triple(n) {
+    return super.triple(n) * super.triple(n);
+  }
+}
+
+console.log(Triple.description);   // 'I triple any number you provide'
+console.log(Triple.triple());      // 3
+console.log(Triple.triple(6));     // 18
+
+var tp = new Triple();
+
+console.log(BiggerTriple.triple(3));        // 81 (not affected by parent's instantiation)
+console.log(BiggerTriple.description);      // 'I square the triple of any number you provide'
+console.log(BiggerTriple.longDescription);  // undefined
+console.log(BiggerTriple.customName);       // 'Tripler'
+
+console.log(tp.triple());         // 'tp.triple is not a function'.
+
+ +

Wywoływanie metod statycznych z innych metod statycznych

+ +

W celu wywołania metody lub właściwości statycznej z innej metody statycznej tej samej klasy można użyć słowa kluczowego this.

+ +
class StaticMethodCall {
+  static staticProperty = 'static property';
+  static staticMethod() {
+    return 'Static method and ' + this.staticProperty + ' has been called';
+  }
+  static anotherStaticMethod() {
+    return this.staticMethod() + ' from another static method';
+  }
+}
+StaticMethodCall.staticMethod();
+// 'Static method and static property has been called'
+
+StaticMethodCall.anotherStaticMethod();
+// 'Static method and static property has been called from another static method'
+ +

Wywoływanie metod statycznych z konstruktora i innych metod

+ +

Metody statyczne nie są dostępne przez this w metodach niestatycznych. Trzeba je wywołać, używając nazwy klasy: CLASSNAME.STATIC_METHOD_NAME() / CLASSNAME.STATIC_PROPERTY_NAME lub jako metody właściwości constructor: this.constructor.STATIC_METHOD_NAME() / this.constructor.STATIC_PROPERTY_NAME.

+ +
class StaticMethodCall {
+  constructor() {
+    console.log(StaticMethodCall.staticProperty); // 'static property'
+    console.log(this.constructor.staticProperty); // 'static property'
+    console.log(StaticMethodCall.staticMethod()); // 'static method has been called.'
+    console.log(this.constructor.staticMethod()); // 'static method has been called.'
+  }
+
+  static staticProperty = 'static property';
+  static staticMethod() {
+    return 'static method has been called.';
+  }
+}
+ +

Specyfikacje

+ + + + + + + + + + + + + + + + + + + +
SpecyfikacjaStatusKomentarz
{{SpecName('ES2015', '#sec-class-definitions', 'Class definitions')}}{{Spec2('ES2015')}}Definicja początkowa.
{{SpecName('ESDraft', '#sec-class-definitions', 'Class definitions')}}{{Spec2('ESDraft')}}
+ +

Kompatybilność

+ + + +

{{Compat("javascript.classes.static")}}

+ +

Zobacz też

+ + -- cgit v1.2.3-54-g00ecf