Úvod do tříd v JavaScriptu

JavaScript je programovací jazyk založený na prototypu a každý objekt v JavaScriptu zdědí skrytý prototype vlastnost, kterou lze použít k rozšíření vlastností a metod.

ECMAScript 2015 (ES6) poprvé představil koncept tříd v JavaScriptu. V objektově orientovaném programovacím jazyce je třída šablonou pro vytváření objektů s vlastnostmi a metodami stejného druhu. To však není případ JavaScriptu.

Třídy JavaScriptu nejsou nic jiného než jen syntaktický cukr nad existující dědičnost založenou na prototypech a funkce konstruktoru.

Definování třídy

Novou třídu v JavaScriptu můžete definovat pomocí class klíčové slovo:

class User {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    greeting() {
        return `Hey ${this.name} 👋`;
    }
}

Výše uvedený příklad deklaruje User třída se dvěma počátečními vlastnostmi:name a age . Chcete-li vytvořit novou instanci User , musíte použít new klíčové slovo:

const alex = new User('Alex Jones', 32);

console.log(alex.greeting()); // Hey Alex Jones 👋

Když je vytvořen nový objekt, constructor() metoda je volána automaticky pomocí new klíčové slovo.

Výraz třídy

Stejně jako funkce šipek lze třídy definovat také uvnitř jiného výrazu. Výraz třídy může být pojmenován nebo pojmenován.

Zde je příklad výrazu nepojmenované třídy:

const Circle = class {
    constructor(radius, color) {
        this.radius = radius;
        this.color = color;
    }

    area() {
        return Math.PI * this.radius * this.radius;
    }
}

const circle = new Circle(10, 'Blue');

console.log(circle.area()); // 314.1592653589793

Pokud chcete odkazovat na název třídy uvnitř těla, můžete definovat výraz pojmenované třídy . Název je viditelný pouze v rámci samotného výrazu třídy:

const Animal = class NamedAnimal {
    constructor() {
    }

    whoIsThere() {
        return NamedAnimal.name;
    }
};

const obj = new Animal();

console.log(obj.whoIsThere()); // NamedAnimal

Metody instance

Můžete vytvořit metody třídy se stejnou syntaxí jako objektové metody. Metoda je v podstatě funkce definovaná v rámci třídy a přístupná každé instanci této třídy.

Například v Circle třídy výše jsme již definovali metodu s názvem area() která vrací oblast kruhu.

Definujme další třídu s názvem Rectangle pomocí metody s názvem area() který vypočítá a vrátí plochu obdélníku:

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

    area() {
        return this.width * this.height;
    }
}

const rect = new Rectangle(15, 20);

console.log(rect.area()); // 300

Statické metody

Statická metoda je funkce definovaná v rámci třídy, ke které lze přistupovat bez vytváření nového objektu této třídy.

Protože statické metody jsou definovány na úrovni třídy, můžete je volat přímo pomocí názvu třídy.

V JavaScriptu musíte použít static klíčové slovo pro definování statické metody:

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

    static square(length) {
        return new Rectangle(length, length);
    }
}

const square = Rectangle.square(7);
square.height; // 7
square.width; // 7

Getters and setters

Stejně jako objektově orientovaná třída může třída JavaScriptu také obsahovat metody getter a setter. Tyto metody můžete použít k formátování a ověřování vlastností třídy.

Zde je příklad User třída, která implementuje getry a nastavovače:

class User {
    constructor(name, age) {
        // Invokes setter methods
        this.name = name;
        this.age = age;
    }

    get name() {
        return this._name;
    }

    set name(value) {
        this._name = value;
    }

    get age() {
        return `${this._name} is ${this._age} years old!`;
    }

    set age(value) {
        if (typeof value !== 'number') {
            throw new Error(`Age must be a number.`);
        }
        this._age = value;
    }
}

const john = new User('John White', 21);

console.log(john.name); // John White
console.log(john.age); // John White is 21 years old!

// Throws an error
const maria = new User('Maria', '32');
// Error: Age must be a number.

Všimněte si metod getter a setter pro age vlastnictví. Formátujeme age hodnotu, než jej vrátíte zpět. Také, když age je nastaveno, ujistíme se, že je to číslo. Když to zkusíte, nastaví se nečíselná hodnota pro age vlastnost, metoda setter vyvolá výjimku.

Názvy vypočítaných metod

Můžete také definovat názvy vypočítaných metod pomocí závorky [...] ve třídě JavaScript:

class User {
    constructor(name) {
        this.name = name;
    }

    ['hi' + 'There']() {
        return ` 👋 ${this.name}`;
    }
}

const alex = new User('Alex');

console.log(alex.hiThere()); //  👋 Alex

Dědičnost

Jednou z výhod používání tříd je, že můžete snadno rozšířit funkčnost vytvořením nové třídy založené na nadřazené třídě. To nám umožňuje znovu použít stejný kód pro jiné objekty, které jsou podobné, ale potřebují nějaké další nebo specifičtější funkce.

Když třída JavaScriptu rozšiřuje další třídu, zdědí všechny statické a instanční metody, gettery a nastavovače a vypočítané vlastnosti.

Podtřída pak definuje další metody, statiku, getry a settery. Může také přepsat metody rodičovské třídy, statiku, getry a settery.

Zde je příklad Square třída, která rozšiřuje funkčnost Rectangle :

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

    area() {
        return this.width * this.height;
    }
}

class Square extends Rectangle {
    constructor(length) {
        // `super` refers to the parent class' constructor
        super(length, length);
    }

    inradius() {
        return this.width / 2;
    }
}

const square = new Square(10);

square.area();          // 100 (from Rectangle)
square.inradius();      // 5 (from Square)

Podívejte se na tento článek, kde se dozvíte více o JavaScriptových třídách, objektech a prototypech.