Strona główna / Artykuły

Dekonstrukcja w JavaScript dla tablic i obiektów

Naucz się dekonstrukcji w JavaScript z jasnymi wyjaśnieniami po angielsku — pomijanie elementów w tablicach i wartości domyślne, aliasy obiektów, rozbieranie zagnieżdżone, zamiana wartości oraz parametry funkcji (ES6+).

Wydawca: REACTAPP.TOP5 min czytania1129 słów

Źródła: Entendiendo la desestructuración en Javascript

Destrukcja oznacza pobranie wartości strukturalnej i jej podzielenie w taki sposób, aby każda część mogła być używana osobno. Zamiast wielokrotnie uzyskiwać dostęp do tego samego kontenera, deklarujesz wymaganą strukturę i przypisujesz nazwy w jednym kroku.

Po prostu mówiąc, to jak wyjmowanie kilku osobistych przedmiotów z plecaka podróżnego. Plecak reprezentuje tablicę, obiekt, ciąg znaków lub dowolną strukturę, która zachowuje się jak iterowalny obiekt. Osobiste przedmioty to poszczególne wartości, które chcesz wykorzystać. Iteratory i iterowalne obiekty zasługują na osobne omówienie później; na razie wystarczy wiedzieć, że tablice oraz wiele wbudowanych funkcji już umożliwia takie rozpakowywanie wartości.

Dzięki temu modelowi mentalnemu te części można przypisać do zmiennych w sposób bardziej uporządkowany niż poprzez pisanie oddzielnych wyrażeń indeksowych dla każdego elementu:

const numbers = [ 1, 2, 3 ];

// En lugar de realizar esto:
let x = numbers[0];
let y = numbers[1];
let z = numbers[2];

// Simplemente podemos hacer esto:
let [ x, y, z ] = numbers;

console.log(x); // 1
console.log(y); // 2
console.log(z); // 3

Podczas tej samej operacji przypisywania możesz pominąć wartości, które cię nie interesują, pozostawiając puste przerwy między przecinkami. Dzięki temu zachowasz potrzebne powiązania, nie musząc tworzyć zmiennych do wyrzucenia:

const numbers = [ 1, 2, 3 ];

// x = 1, z = 3
let [ x, , z ] = numbers;

// y = 2, z = 3
let [ , y, z ] = numbers;

// x = 1, y = 2, z = 3, a = undefined
let [ x, y, z, a ] = numbers;

Możesz również wprowadzić nowe powiązania z wartościami domyślnymi, gdy jakaś pozycja jest brakująca lub niezdefiniowana, co jest przydatne w przypadku opcjonalnych pozycji na końcu:

const numbers = [ 1, 2, 3 ];

// x = 1, y = 2, z = 3, a = 4
let [ x, y, z, a = 4 ] = numbers;

Zagnieżdżone struktury są rozpakowywane w ten sam sposób – można uzyskać dostęp do wewnętrznej tablicy bez użycia tymczasowych zmiennych, które istnieją tylko po to, by usunąć jedną warstwę:

const alphanumericSequence = [ 'a', 'b', 'c', [1, 2, 3] ];

// numericSequence = [ 1, 2, 3 ]
let [ , , , numericSequence ] = alphanumericSequence;

// x = 1, y = 2, z = 3
let [ , , , [ x, y, z ] ] = alphanumericSequence;

Praktycznym trikiem jest zamiana dwóch zmiennych bez tworzenia zmiennej tymczasowej. Operacja destrukcyjnego przypisywania może wymienić obie strony w jednym zdaniu, co eliminuje częsty problem błędów typu „off-by-one”, które pojawiają się, gdy ludzie tworzą osobną trzecią zmienną:

let a = 1;
let b = 2;

// En lugar de hacer esto:
let temp = a;
a = b;
b = temp;

// Simplemente podemos hacer esto:
[ a, b ] = [ b, a ];

console.log(a); // 2
console.log(b); // 1

Rozbieranie obiektów

aliasy. To jest główna różnica w porównaniu z rozpakowywaniem tablic, gdzie liczy się tylko kolejność.

const employee = {
  name: 'Julia',
  age: 27,
  job: {},
  workSchedule: {}
};

// El nombre de las variables coincide con el nombre
// de las propiedades del objeto.
let { name, age, job, workSchedule } = employee;

aliasy, zachowując jednocześnie oryginalne klucze:

let {
  name:employeeName,
  age:employeeAge,
  job:employeeJob,
  workSchedule:employeeWorkSchedule
} = employee;

Domyślne wartości można stosować również podczas rozpakowywania, wypełniając luki gdy dana właściwość jest nieobecna lub nieskończona, bez konieczności osobnej weryfikacji wartości null później:

let {
  name = 'john',
  age = 18,
  job = 'worker',
  workSchedule = null
} = employee;

// Incluso utilizar un alias durante este proceso:
let {
  name:employeeName = 'john',
  age:employeeAge = 18,
  job:employeeJob = 'worker',
  workSchedule:employeeWorkSchedule = null
} = employee;

Obiekty ułożone wewnątrz siebie rozpakowują się według tego samego zasady: określ ścieżkę w wzorcu i powiąż tylko te elementy, których potrzebujesz:

const employee = {
  name: 'Julia',
  age: 27,
  job: {},
  workSchedule: {
    mon: {
      open: 12,
      close: 22,
    },
    tue: {
      open: 11,
      close: 23,
    },
    wed: {
      open: 23,
      close: 5,
    }
  }
};

let { workSchedule: { mon, tue, wed } } = employee;

console.log(mon); // { open: 12, close: 22 }
console.log(tue); // { open: 11, close: 23 }
console.log(wed); // { open: 23, close: 5 }

Bądź ostrożny przy głębokim ułożeniu elementów. Przenoszenie wartości przez wiele poziomów w jednym wzorcu szybko pogarsza czytelność i sprawia, że modyfikacje stają się niestabilne, gdy struktura ulega zmianie:

const employee = {
  name: 'Julia',
  age: 27,
  workSchedule: {
    mon: {
      open: {
        from: 12
      },
      close: {
        to: 22
      }
    }
  }
};

// Multiples niveles de anidación
let { workSchedule: { mon: { open: {from}, close: {to} } } } = employee;

console.log(from); // 12
console.log(to);   // 22

Rozbieranie obiektów sprawdza się również w parametrach funkcji. Zamiast długiej listy pozycyjnej, przyjmij obiekt opcji i rozpakuj jego pola na granicy, wraz z domyślnymi wartościami:

const dispatchDelivery = (endpoint, { userId, time = '00:00', address, items = [] }) => {
  // Some action...
};

dispatchDelivery('api/dispatch-delivery', {
  userId: 3392,
  address: 'Villas del Sol',
  time: '22:30',
  items: [ 'Beers', 'Sodas', 'Doritos' ]
});

dispatchDelivery('api/dispatch-delivery', {
  userId: 5423,
  address: 'Villas del Sol'
});

Wynikiem jest podpis bardziej bogaty i łatwiejszy do odczytania — szczególnie wtedy, gdy funkcja wymaga wielu opcji, których wywołujący nie zawsze dostarczą. Destructuring to podstawowe narzędzie nowoczesnego JavaScriptu, które staje się jeszcze bardziej wyraźne w połączeniu z operatorem spread, który umożliwia dodatkowe wzorce kompozycji do klonowania i łączenia struktur.

Należy pamiętać o podstawach języka: destructuring pojawił się w ECMAScript 2015 (ES6). Starsze silniki wymagają kroku transpilacji lub strategii polyfill, zanim będzie można go używać w przeglądarce produkcyjnych lub starszych środowiskach wykonawczych.

Literatura pokrewna

  • Naprawdowe plany JavaScripta: prototypy, delegacja i funkcje — Dlaczego klasy to jedynie „cukier składniowy” w porównaniu z prototypami, jak delegacja różni się od klasycznej dziedziczenia, gdzie to powoduje problemy oraz co daje styl funkcyjny w JavaScriptie.