To tłumaczenie jest niekompletne. Pomóż przetłumaczyć ten artykuł z języka angielskiego.

Klasy w Javascript zostały wprowadzone ECMAScript 2015 to 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". Pododnie 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ć wyrażenia 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 (hoisted) a klas nie. Najpierw musisz zadeklarować swoją klasę by mieć do niej dostęp, w przeciwnym razie kod, jak ten poniżej, wygeneruje wyjątek 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.

// nienazwane
var Prostokat = class {
  constructor(wysokosc, szerokosc) {
    this.wysokosc = wysokosc;
    this.szerokosc = szerokosc;
  }
};

// nazwane
var Prostokat = class Prostokat {
  constructor(wysokosc, szerokosc) {
    this.wysokosc = wysokosc;
    this.szerokosc = szerokosc;
  }
};

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 definuje 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 scisł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 wyjątek SyntaxError.

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

Prototypy

Zobacz też definiowanie metod.

class Prostokat {
  constructor(wysokosc, szerokosc) {
    this.wysokosc = wysokosc;
    this.szerokosc = szerokosc;
  }
  
  get pole() {
    return this.liczPole();
  }

  liczPole() {
    return this.wysokosc * this.szerokosc;
  }
}

const kwadrat = new Prostokat(10, 10);

console.log(kwadrat.pole);

Metody statyczne

Słowo kluczowe static definiuje metodę statyczną w klasie. Statyczne metody 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 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);

console.log(Punkt.odleglosc(p1, p2));

Boxing with prototype and static methods

When a static or prototype method is called without an object valued "this" (or with "this" as boolean, string, number, undefined or null), then the "this" value will be undefined inside the called function. Autoboxing will not happen. The behaviour will be the same even if we write the code in non-strict mode.

class Animal { 
  speak() {
    return this;
  }
  static eat() {
    return this;
  }
}

let obj = new Animal();
let speak = obj.speak;
speak(); // undefined

let eat = Animal.eat;
eat(); // undefined

If we write the above code using traditional function based classes, then autoboxing will happen based on the "this" value for which the function was called.

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

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 {
  speak() {
    console.log(this.name + ' barks.');
  }
}

var d = new Dog('Mitzie');
d.speak();

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.');
  }
}

var d = new Dog('Mitzie');
d.speak();

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ć 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

var d = new Dog('Mitzie');
d.speak(); //Mitzie makes a noise.

Species

You might want to return Array objects in your derived array class MyArray. The species pattern lets you override default constructors.

For example, when using methods such as map() that returns the default constructor, you want these methods to return a parent Array object, instead of the MyArray object. The Symbol.species symbol lets you do this:

class MyArray extends Array {
  // Overwrite species to the parent Array constructor
  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

Super class calls with super

The super keyword is used to call functions on an object's parent.

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.');
  }
}

Mix-ins

Abstract subclasses or mix-ins are templates for classes. An ECMAScript class can only have a single superclass, so multiple inheritance from tooling classes, for example, is not possible. The functionality must be provided by the superclass.

A function with a superclass as input and a subclass extending that superclass as output can be used to implement mix-ins in ECMAScript:

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

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

A class that uses these mix-ins can then be written like this:

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

Specifications

Specification Status Comment
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'Class definitions' in that specification.
Standard Initial definition.
ECMAScript Latest Draft (ECMA-262)
The definition of 'Class definitions' in that specification.
Draft  

Browser compatibility

We're converting our compatibility data into a machine-readable JSON format. This compatibility table still uses the old format, because we haven't yet converted the data it contains. Find out how you can help!

Feature Chrome Firefox (Gecko) Edge Internet Explorer Opera Safari
Basic support 42.0[1]
49.0
45 (45) 13 No support No support 9.0
Feature Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile Chrome for Android
Basic support No support 45.0 (45) ? ? 9 42.0[1]
49.0

[1] Requires strict mode. Non-strict mode support is behind the flag "Enable Experimental JavaScript", disabled by default.

See also

Autorzy i etykiety dokumentu

Ostatnia aktualizacja: freszyk,