Konstruktor vs. Notacja literałowa: Odkryj różne sposoby tworzenia obiektów w JavaScript


Stosowanie technik programowania obiektowego jest jednym z podstawowych paradygmatów języka JavaScript. Aby sprawnie się nimi posługiwać i tworzyć jak najlepsze aplikacje, warto przyswoić sobie odrobinę wiedzy na temat obiektów w JavaScript, gdyż prawie wszystko w tym języku jest traktowane jak obiekt. Nawet podstawowe z założenia typy danych, takie jak liczby czy łańcuchy znaków dostępne są w postaci obiektów.

Dzięki połączeniu technik programowania obiektowego oraz funkcyjnego, nasze aplikacje będą bardziej elastyczne, a kod bardziej czytelny i łatwiejszy w rozbudowie i utrzymaniu. Można powiedzieć, że JavaScript jest dosyć specyficznym językiem, jeśli chodzi o podejście do programowania obiektowego, dlatego ważne jest, aby dobrze zrozumieć mechanizmy leżące u podstaw jego działania, aby efektywnie korzystać z możliwości, które nam oferuje. Na początek zobaczmy jakie sposoby tworzenia obiektów dostępne są w JavaScript.

Wprowadzenie do konstruktorów i notacji literałowej pomoże nam lepiej zrozumieć, jak można efektywnie tworzyć obiekty w JavaScript. Przeanalizujemy różnice między tymi dwoma technikami, abyś mógł odkryć, który sposób najlepiej odpowiada Twoim potrzebom. Czytając dalej, dowiesz się więcej o różnych sposobach tworzenia obiektów w JavaScript i ich zastosowaniach.

Notacja literałowa

Literały obiektowe są jednym z najprostszych sposobów na stworzenie obiektu w języku JavaScript. Zazwyczaj obiekt reprezentuje jakiś byt. Niech to będzie koszyk, jak w poniższym przykładzie:

const cart = {
  cartItems: [],
  addItem(product) {
    // implementacja metody
  }
};

Powyżej zdefiniowaliśmy obiekt cart z własnością cartItems. W stałej cart, zapisaliśmy referencję do instancji koszyka. Tworzenie własności obiektu przy użyciu notacji literałowej polega na tworzeniu par indeks – wartość, zamkniętych między nawiasami klamrowymi. Do własności możemy przypisać dowolną wartość, a także inny obiekt. Z kolei metody obiektu reprezentują czynności, które dany obiekt może wykonywać.

Własności tak utworzonego obiektu możemy usuwać w trakcie działania programu:

delete cart.cartItems;

Konstruktory obiektów

W języku JavaScript, gdy potrzebujemy tworzyć wiele obiektów o identycznej strukturze, notacja literałowa może okazać się niewystarczająca. Powtarzanie kodu może prowadzić do trudności w utrzymaniu i rozbudowie aplikacji. Na szczęście, w takich sytuacjach możemy skorzystać z konstruktorów – funkcji specjalnie zaprojektowanych do tworzenia wielu obiektów o tej samej strukturze. Konstruktor pozwala nam uniknąć powielania kodu i umożliwia elastyczne zarządzanie obiektami.

Konstruktor jest funkcją, która wywołana z operatorem new pozwala na tworzenie wielu obiektów o tej samej strukturze. Utwórzmy sobie przykładowy konstruktor User:

function User(id, name, email) {
  this.id = id;
  this.name = name;
  this.email = email;
}

Aby utworzyć obiekt, należy go zainicjalizować. Jak już pisałem, do tego celu wykorzystuje się słowo kluczowe new:

const john = new User(1, "John", "john@doe.com");
console.log(john.name); // "John"

Jak widać w powyższym przykładzie do konstruktora przekazujemy argumenty, które wykorzystywane są do inicjalizacji obiektu. Zauważmy, że tak utworzony obiekt możemy modyfikować, przykładowo dodając do niego funkcję:

john.greets = function() {
  console.log(`Hello ${this.name}`);
};

Wykorzystanie konstruktorów w JavaScript otwiera drzwi do efektywnego tworzenia wielu obiektów o identycznej strukturze. Dzięki nim możemy uniknąć powielania kodu i utrzymać czytelność oraz łatwość rozbudowy naszych aplikacji. Warto zrozumieć mechanizm działania konstruktorów i wykorzystać go w odpowiednich przypadkach, aby maksymalnie wykorzystać potencjał języka JavaScript. Dzięki konstruktorom możemy skutecznie tworzyć i zarządzać obiektami, dostosowując je do naszych potrzeb i wymagań programistycznych.

Konstruktor Object()

Ten dostarczany domyślnie przez JavaScript typ konstruktora był już przez nas wykorzystywany. Kiedy tworzyliśmy obiekt przy użyciu notacji literałowej, JavaScript niejawnie wywołał konstruktor Object() w celu utworzenia nowego obiektu. Wróćmy do poprzedniego przykładu koszyka i przekonajmy się o tym:

const cart = {};

console.log(cart.constructor == Object); // true

Technicznie rzecz biorąc, utworzenie obiektu w ten sposób w zasadzie nie różni się od użycia literału obiektowego.

const cart = new Object();

cart.cartItems = [];

Konstruktor vs Notacja Literałowa

Konstruktor w JavaScript może być bardziej efektywny niż notacja literałowa w różnych sytuacjach. Oto kilka przykładów, w których warto rozważyć użycie konstruktora:

  1. Tworzenie wielu obiektów o identycznej strukturze: Jeśli masz potrzebę tworzenia wielu obiektów o tej samej strukturze, konstruktor staje się wydajniejszym rozwiązaniem. Możesz zdefiniować konstruktor raz, a następnie tworzyć wiele instancji obiektów, przekazując różne wartości argumentów. To pozwala na bardziej efektywne i czytelne zarządzanie kodem.
  2. Inicjalizacja obiektów na podstawie zewnętrznych danych: Jeżeli chcesz tworzyć obiekty na podstawie danych pobranych z zewnętrznych źródeł, konstruktor staje się bardziej elastycznym rozwiązaniem. Możesz przekazać te dane jako argumenty konstruktora i wykorzystać je do inicjalizacji właściwości obiektu. To ułatwia tworzenie obiektów na podstawie zmiennych warunkowych lub dynamicznie zmieniających się danych.
  3. Dziedziczenie i rozszerzanie funkcjonalności: Konstruktor umożliwia dziedziczenie i rozszerzanie funkcjonalności obiektów poprzez manipulację prototypem. Możesz tworzyć hierarchie obiektów, które dziedziczą wspólne właściwości i metody. Dzięki temu tworzenie i zarządzanie kodem staje się bardziej modularne i łatwiejsze w utrzymaniu.
  4. Praca z bibliotekami i frameworkami: Wielu popularnych bibliotekach i frameworkach JavaScript, takich jak React czy Angular, konstruktor jest powszechnie używany do tworzenia instancji komponentów i usług. Te narzędzia wymagają użycia konstruktora, co sprawia, że jest on wygodnym i zalecanym rozwiązaniem.

Konstruktor i notacja literałowa są dwoma głównymi sposobami tworzenia obiektów w JavaScript. Oba mają swoje zalety i w niektórych przypadkach notacja literałowa może być bardziej odpowiednia. Ważne jest zrozumienie różnic między nimi i wybór odpowiedniego podejścia w zależności od potrzeb projektu.

Prototypy obiektów

Prototypy są jednym z najciekawszych elementów w języku JavaScript. Zobaczmy co dają nam prototypy na prostym przykładzie:

function User(id, name, email) {
  // własności
  this.greets = function() {
    console.log(`Hello ${this.name}`);
  };
}

const john = new User(1, "John", "john@doe.com");
john.greets(); // Hello John

const bob = new User(2, "Bob", "bob@example.com");
bob.greets(); // Hello Bob

Problem z powyższym przykładem polega na tym, że jest to mało wydajny sposób tworzenia obiektów. Każda nowa instancja utworzona za pomocą konstruktora User będzie posiadała własną metodę greets().

Bardziej efektywne będzie w tym przypadku wykorzystanie mechanizmu prototypowania:

function User(id, name, email) {
  // własności
}

User.prototype.greets = function() {
  console.log(`Hello ${this.name}`);
}

Jak widać do obiektu prototypu konstruktora (User.prototype) przypisaliśmy metodę greets(). Powyższy zapis sprawia, że wszystkie obiekty utworzone za pomocą konstruktora User() będą miały dostęp do metody greets(). Innymi słowy prototyp jest własnością konstruktora, w którym definiujemy elementy, które mają być dziedziczone.

Object.create()

Obiekty możemy tworzyć również wykorzystując metodę Object.create(). Ta metoda oprócz utworzenia nowego obiektu, pozwala na ustawienie prototypu tworzonego obiektu.

const bob = Object.create(john);

W powyższym przykładzie utworzyliśmy nowy obiekt bob z obiektu john użytego jako prototyp. W ten sposób obiekt bob odziedziczył zarówno własności jak i metody obiektu john. Jak widać w metodzie tej nie ma potrzeby stosowania konstruktora.

Klasy

Standard ES6, wprowadza jeszcze jeden sposób tworzenia obiektów. Są nim klasy. Zobaczmy jak wygląda przykładowa definicja:

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

  greets() {
    // kod metody
  }
}

Klasa User jest tak naprawdę funkcją, a sama koncepcja klas została wprowadzona w celu uproszczenia posługiwania się konstruktorami, prototypami i dziedziczeniem. Obiekty tworzy się w sposób identyczny jak w przypadku konstruktorów:

const john = new User(1, "John", "john@doe.com");

Warto zaznaczyć, że wszystkie metody zawarte w definicji klasy, są związane z jej prototypem. Dzięki temu metody klasy nie są powielane w nowo tworzonych obiektach.

Powyższe metody umożliwiają tworzenie obiektów w JavaScript. Wybór odpowiedniej metody zależy od konkretnej sytuacji i preferencji programisty.


Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *