Objekty, prototypy a třídy v JavaScriptu

JavaScript je založen na jednoduchém objektově orientovaném programovacím modelu s objekty, které jsou základní součástí jazyka. Téměř vše v JavaScriptu je objekt. Na rozdíl od jiných objektově orientovaných programovacích jazyků, jako je Java, jsou objekty JavaScript velmi flexibilní .

Objekty

Objekt je kolekce párů klíč-hodnota nazývaných vlastnosti. Klíč vlastnosti je řetězec nebo symbol (známý také jako název vlastnosti ) a hodnota může být jakákoliv. Existuje několik způsobů, jak vytvořit objekt v JavaScriptu. Nejjednodušším a nejoblíbenějším způsobem je použití objektového doslovného syntaxe:

const user = {
    fisrtName: 'John',
    lastName: 'Doe',
    age: 29 
};

Objekty lze také vytvářet pomocí operátoru new . new klíčové slovo lze použít buď s vestavěným Object funkce konstruktoru nebo uživatelsky definovaná funkce konstruktoru:

// in-built constructor function
const user = new Object();
user.fisrtName = 'John';
user.lastName = 'Doe';
user.age = 29;

// user-defined constructor function
function User(fisrtName, lastName, age) {
    this.fisrtName = fisrtName;
    this.lastName = lastName;
    this.age = age;
};

const user = new User('John', 'Doe', 29);

Hodnota vlastnosti může být také funkcí. Taková vlastnost se nazývá metoda:

const user = {
    fisrtName: 'John',
    lastName: 'Doe',
    age: 29,
    fullName: function () {
        return `${this.fisrtName} ${this.lastName}`;
    }
};

Hodnoty vlastností jsou přístupné pomocí obou teček (. ) a hranatou závorku ([] ) zápis:

// dot notation
console.log(user.fullName()); // John Doe
console.log(user.age); // 29

// square bracket notation - does not work for methods
console.log(user['fisrtName']); // John

Ke stávajícímu objektu můžete přidat nové vlastnosti pouhým přiřazením hodnot:

user.country = 'United States';

// method can also be added
user.ageRange = function() {
    return `${this.age - 5}-${this.age + 5}`;
}

Chcete-li odstranit vlastnost z objektu, použijte delete operátor:

delete user.age;

K iteraci přes všechny klíče objektu můžeme použít for...in smyčka:

for (const key in user) {
    console.log(user[key]);
}

Doslovnou syntaxi objektu lze použít pouze k vytvoření jednoho objektu. Chcete-li vytvořit více objektů stejného typu, musíte použít funkci konstruktoru objektů:

function Animal(name, icon) {
    this.name = name;
    this.icon = icon;
};

const rabbit = new Animal('Rabbit','🐰');
const cat = new Animal('Cat','🐱');

Nemůžeme přímo přiřadit hodnoty konstruktoru objektu, abychom přidali nové vlastnosti a metody. Do funkce konstruktoru objektu musí být přidány nové vlastnosti:

Animal.color = 'Red'; // wrong way

// correct way
function Animal(name, icon, color) {
    // ...
    this.color = color;
};

Prototypy

Všechny objekty v JavaScriptu dědí vlastnosti a metody z jiného objektu zvaného prototyp. prototype vlastnost nám umožňuje přidávat nové vlastnosti a metody do existujících konstruktorů objektů. Nové vlastnosti jsou sdíleny mezi všemi instancemi zadaného typu, nikoli pouze jednou instancí objektu.

Přidejme nové vlastnosti všem objektům typu Animal přes prototyp:

// add property
Animal.prototype.color = 'White';

// add method
Animal.prototype.meow = function() {
    if(this.name === 'Cat') {
        return `${this.name} can meow!`;
    } else {
        return `${this.name} cannot meow!`;
    }
}

Nyní výše cat a rabbit objekty mají vlastnost color a metoda meow() protože prototype z Animal má je:

console.log(cat.color); // White
console.log(rabbit.meow()); // Rabbit cannot meow!
console.log(cat.meow()); // Cat can meow!

Pokud chcete získat přístup ke sdílenému prototype vlastnost prostřednictvím instance konkrétního typu, existuje __proto__ nemovitost k dispozici. Prostřednictvím této vlastnosti můžete upravit stávající vlastnosti prototypu nebo dokonce přidat nové vlastnosti. Od prototype vlastnost je sdílena mezi všemi instancemi, změny provedené v jedné instanci prototype vlastnost nebo metoda se projeví ve všech případech:

cat.__proto__.color = 'Black';
cat.__proto__.eatMeat = true;

console.log(rabbit.color); // Black
console.log(rabbit.eatMeat); // true

Podobně jako u objektů prototype vlastnost nebo metodu lze odstranit pomocí delete operátor:

delete cat.__proto__.eatMeat;
// OR
delete Animal.prototype.eatMeat;

console.log(rabbit.eatMeat); // undefined

Jak můžeme vidět výše, prototype vlastnost je základní součástí základů objektů v JavaScriptu. Jakékoli změny provedené v této vlastnosti ovlivní všechny instance daného typu objektu.

Třídy

Koncept tříd byl zaveden v JavaScriptu v ES6 (ECMA2015). V paradigmatu objektově orientovaného programování je třída plánem pro vytváření objektů s vlastnostmi a metodami při zapouzdření detailů implementace od uživatele. Koncept skutečných tříd však v JavaScriptu neexistuje.

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

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

    sayHi() {
        return `👋 ${this.name}!`;
    }
}

Nyní, pokud chceme vytvořit novou instanci Person třídy, musíme použít new operátor:

const bill = new Person('Bill', 25);
console.log(bill.sayHi()); // 👋 Bill!

Když vytvoříme objekt Person třídy, konstruktor třídy provede následující:

  1. Vytvořte novou funkci s názvem Person a zkopírujte do něj všechny vlastnosti deklarované uvnitř konstruktoru (name a age ).
  2. Přidejte všechny metody třídy, například sayHi() , na Person.prototype vlastnictví.

Když poté zavoláme jakoukoli metodu objektu, je převzata z prototype vlastnictví. Podívejte se na tento článek, kde se dozvíte více o třídách JavaScript.

Shrnutí

Objekty jsou důležitou součástí jazyka JavaScript. Téměř vše v JavaScriptu je objekt.

  • Objekt je kolekce vlastností klíč–hodnota. Objekt lze vytvořit buď pomocí doslovné syntaxe objektu, nebo pomocí syntaxe funkce konstruktoru objektu.
  • Kdykoli je v JavaScriptu vytvořena nová funkce, stroj JavaScript automaticky připojí prototype majetek k tomu. Změny provedené v této vlastnosti jsou sdíleny mezi všemi instancemi určitého typu objektu. Je to skvělý způsob, jak přidat nové vlastnosti do existujících funkcí konstruktoru objektů.
  • ES6 přinesl do JavaScriptu třídy, které nejsou ničím jiným než novým způsobem psaní funkcí konstruktoru s využitím funkčnosti prototypu.

Pokud se chcete o objektech dozvědět více, zde je podrobný průvodce MDN, který vysvětluje, jak používat objekty, vlastnosti a metody.