Składnia przypisania destrukturyzującego jest wyrażeniem w JavaScript, które pozwala na wyciągnięcie danych z tablic bądź obiektów do odrębnych zmiennych.

Składnia

var a, b, rest;
[a, b] = [1, 2];
console.log(a); // 1
console.log(b); // 2

[a, b, ...rest] = [1, 2, 3, 4, 5];
console.log(a); // 1
console.log(b); // 2
console.log(rest); // [3, 4, 5]

({a, b} = {a:1, b:2});
console.log(a); // 1
console.log(b); // 2

// ES2016 - nie zaimplementowane w przeglądarce Firefox 47a01
({a, b, ...rest} = {a:1, b:2, c:3, d:4}); 

Opis

Wyrażenie literału obiektowego i tablicowego umożliwiają łatwe tworzenie paczek danych ad-hoc

var x = [1, 2, 3, 4, 5];

Składnia przypisania destrukturyzacyjnego używa podobnej składni, ale z lewej strony przypisania definiujemy, które elementy wyciągnąć ze zmiennej źródłowej.

var x = [1, 2, 3, 4, 5];
var [y, z] = x;
console.log(y); // 1
console.log(z); // 2

Funkcjonalność ta jest podobna do tych obecnych w językach takich jak Pearl i Python.

Destrukturyzacja tablic

Podstawowe przypisanie zmiennych

var foo = ["one", "two", "three"];

var [one, two, three] = foo;
console.log(one); // "one"
console.log(two); // "two"
console.log(three); // "three"

Przypisanie oddzielne od deklaracji

Zmiennej można przypisać wartość poprzez destrukturyzację oddzielnie od deklaracji tej zmiennej.

var a, b;

[a, b] = [1, 2];
console.log(a); // 1
console.log(b); // 2

Domyślne wartości

Zmiennej można przypisać wartość domyślną, w wypadku, gdy wartość wyciągnięta z tablicy jest niezdefiniowana - undefined.

var a, b;

[a=5, b=7] = [1];
console.log(a); // 1
console.log(b); // 7

Zamiana zmiennych

Dwie zmienne mogą zamienić się miejscami przy wykorzystaniu jednego wyrażenia destrukturyzującego.

Bez wyrażenia destrukturyzującego, zamiana zmiennych wymaga zmiennej tymaczasowej (bądź, w niektórych językach niskiego poziomu, tricku XOR-swap).

var a = 1;
var b = 3;

[a, b] = [b, a];
console.log(a); // 3
console.log(b); // 1

Parsowanie tablicy zwróconej przez funkcję

Zwrócenie tablicy poprzez funkcję zawsze było możliwe. Destrukturyzacja może sprawić, że praca ze zwróconymi wartościami typu array będzie bardziej zwięzła.

W tym przykładzie, f() zwraca wartości [1, 2] jako jej wyjście, mogą one być sparsowane w jednej linijce poprzez użycie destrukturyzacji.

function f() {
  return [1, 2];
}

var a, b; 
[a, b] = f(); 
console.log(a); // 1
console.log(b); // 2

Ignorowanie niektórych zwróconych wartości

Możesz zignorować zwrócone wartości, którymi nie jesteś zainteresowany.

function f() {
  return [1, 2, 3];
}

var [a, , b] = f();
console.log(a); // 1
console.log(b); // 3

Możesz także zignorować wszystkie zwrócone wartości:

[,,] = f();

 

Przypisanie reszty tablicy do zmiennej

Podczas destrukturyzacji array'a możesz wypakować i przypisać jego pozostałą część do zmiennej używając operatora reszty:

var [a, ...b] = [1, 2, 3];
console.log(a); // 1
console.log(b); // [2, 3]

Zwróć uwagę, że zostanie wyrzucony SyntaxError jeśli końcowy przecinek będzie użyty z lewej strony wyrażenia z elementem reszty: 

var [a, ...b,] = [1, 2, 3];
// SyntaxError: rest element may not have a trailing comma

Wypakowywanie wartości z wyników wyrażenia regularnego

Gdy metoda wyrażenia regularnego  exec() znajdzie pasujący element, zwraca ona tablicę zawierającą kolejno cały string zawierajacy pasujące elementy, a później elementy stringa, które pasowały do każdej grupy wyrażenia regularnego znajdującej się w nawiasach. Wyrażenie destrukturyzujące pozwala na łatwe wypakowanie elementów tej tablicy ignorując pełny string, gdy nie jest on potrzebny. 

function parseProtocol(url) {
  var parsedURL = /^(\w+)\:\/\/([^\/]+)\/(.*)$/.exec(url);
  if (!parsedURL) {
    return false;
  }
  console.log(parsedURL); // ["https://developer.mozilla.org/en-US/Web/JavaScript", "https", "developer.mozilla.org", "en-US/Web/JavaScript"]

  var [, protocol, fullhost, fullpath] = parsedURL;
  return protocol;
}

console.log(parseProtocol('https://developer.mozilla.org/en-US/Web/JavaScript')); // "https"

Destrukturyzacja obiektów

Podstawowe przypisanie

var o = {p: 42, q: true};
var {p, q} = o;

console.log(p); // 42
console.log(q); // true 

Przypisanie bez deklaracji

Zmiennej można przypisać wartość poprzez destrukturyazację oddzielnie od deklaracji tej zmiennej.

var a, b;

({a, b} = {a:1, b:2});

Nawiasy( .. ) na krawędziach wyrażenia przypisania są składnią wymaganą podczas używania wyrażenia destrukturyzującego literał obiektowy bez deklaracji.

{a, b} = {a:1, b:2} nie jest poprawną składnią samą w sobie, ponieważ {a, b} z lewej strony wyrażenia jest odbierana jako blok, a nie literał obiektowy.

Ale już, ({a, b} = {a:1, b:2}) jest poprawne, tak samo jak var {a, b} = {a:1, b:2}

Przypisanie do nowych nazw zmiennych

Zmienna może być wyciągnięta z obiektu i przypisana do zmiennej z inną nazwą niż nazwa właściwości obiektu.

var o = {p: 42, q: true};
var {p: foo, q: bar} = o;
 
console.log(foo); // 42 
console.log(bar); // true  

Wartości domyślne

Zmiennej można przypisać wartość domyślną, w wypadku, gdy wartość wyciągnięta z obiektu jest undefined.

var {a=10, b=5} = {a: 3};

console.log(a); // 3
console.log(b); // 5

 

Przypisywanie do nowych nazw zmiennych i zapewnienie wartości domyślnych

Właściwość może być zarówno 1) wypakowana z obiektu i przypisana do zmiennej z inną nazwą 2) może być jej przypisana wartość domyślna, gdy wypakowana wartość jest undefined.

var {a:aa = 10, b:bb = 5} = {a: 3};

console.log(aa); // 3
console.log(bb); // 5

 

Ustawianie domyślnej wartości parametru funkcji 

Wersja ES5

function drawES5Chart(options) {
  options = options === undefined ? {} : options;
  var size = options.size === undefined ? 'big' : options.size;
  var cords = options.cords === undefined ? { x: 0, y: 0 } : options.cords;
  var radius = options.radius === undefined ? 25 : options.radius;
  console.log(size, cords, radius);
  // now finally do some chart drawing
}

drawES5Chart({
  cords: { x: 18, y: 30 },
  radius: 30
});

Wersja ES2015 (ES6)

function drawES2015Chart({size = 'big', cords = { x: 0, y: 0 }, radius = 25} = {}) {
  console.log(size, cords, radius);
  // do some chart drawing
}

// In Firefox, default values for destructuring assignments are not yet implemented (as described below). 
// The workaround is to write the parameters in the following way:
// ({size: size = 'big', cords: cords = { x: 0, y: 0 }, radius: radius = 25} = {})

drawES2015Chart({
  cords: { x: 18, y: 30 },
  radius: 30
});

W definicji funkcji drawES2015Chart() powyżej, destrukturyzowana lewa strona wyrażenia jest przypisana do pustego literału obiektowego z prawej strony: {size = 'big', cords = {x: 0, y: 0}, radius = 25} = {}. Można by było również napisać funkcję bez prawostronnego przypisania. Jednakże jeśli zostawisz prawą stroę przypisania, funkcja będzie szukać przynajmniej jednego argumentu podczas wywołania, natomiast w jej obecnej formie możesz po prostu wywołać drawES2015Chart() bez podawania parametrów. Ten sposób jest użyteczny gdy chcesz mieć możliwość wywołania funkcji bez podawania parametrów, ten drugi może być użyteczny, gdy chcesz być pewny, że obiekt został wprowadzony do funkcji.

Obiekt zagnieżdżony i destrukturyzacja tablic

var metadata = {
    title: "Scratchpad",
    translations: [
       {
        locale: "de",
        localization_tags: [ ],
        last_edit: "2014-04-14T08:43:37",
        url: "/de/docs/Tools/Scratchpad",
        title: "JavaScript-Umgebung"
       }
    ],
    url: "/en-US/docs/Tools/Scratchpad"
};

var { title: englishTitle, translations: [{ title: localeTitle }] } = metadata;

console.log(englishTitle); // "Scratchpad"
console.log(localeTitle);  // "JavaScript-Umgebung"

Iteracja for..of i destrukturyzacja

var people = [
  {
    name: "Mike Smith",
    family: {
      mother: "Jane Smith",
      father: "Harry Smith",
      sister: "Samantha Smith"
    },
    age: 35
  },
  {
    name: "Tom Jones",
    family: {
      mother: "Norah Jones",
      father: "Richard Jones",
      brother: "Howard Jones"
    },
    age: 25
  }
];

for (var {name: n, family: { father: f } } of people) {
  console.log("Name: " + n + ", Father: " + f);
}

// "Name: Mike Smith, Father: Harry Smith"
// "Name: Tom Jones, Father: Richard Jones"

Wyciąganie pól z obiektów przekazanych jako parametr funkcji

function userId({id}) {
  return id;
}

function whois({displayName, fullName: {firstName: name}}){
  console.log(displayName + " is " + name);
}

var user = { 
  id: 42, 
  displayName: "jdoe",
  fullName: { 
      firstName: "John",
      lastName: "Doe"
  }
};

console.log("userId: " + userId(user)); // "userId: 42"
whois(user); // "jdoe is John"

To wyciąga id, displayNamefirstName z obiektu user i wypisuje je.

Wyznaczane nazwy właściwości obiektów i destrukturyzacja

Wyznaczane nazwy waściwości, tak samo jak wh literałach obiektowych, mogą być używane z destrukturyzacją.

let key = "z";
let { [key]: foo } = { z: "bar" };

console.log(foo); // "bar"

 

Reszta w destrukturyzacji obiektów

Własciwości reszty/rozproszenia dla ECMAScript (proponowane, etap 3) dodają składnię reszty do destrukturyzacji. Właściwości reszty zbierają pozostałe klucze, które nie zostały pobrane poprzez wzorzec destrukturyzacji.

let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40}
a; // 10
b; // 20
rest; // { c: 30, d: 40 }

Nipoprawny identyfikator JavaScript jako nazwa własności

Destrukturyzacja może zostać użyta z nazwami własności, które nie są poprawnymi identyfikatorami JavaScript poprzez zapewnienie alternatywnego, poprawnego identyfikatora.

const foo = { 'fizz-buzz': true };
const { 'fizz-buzz': fizzBuzz } = foo;

console.log(fizzBuzz); // "true"

 

Specyfikacje

Specification Status Comment
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'Destructuring assignment' in that specification.
Standard Definicja wstępna.
ECMAScript Latest Draft (ECMA-262)
The definition of 'Destructuring assignment' in that specification.
Draft  

Kompatybilność przeglądarek

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 49.0 2.0 (1.8.1) 14 No support No support 7.1
Computed property names 49.0 34 (34) 14 No support No support No support
Spread operator 49.0 34 (34) 12[1] ? ? ?
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile Chrome for Android
Basic support No support 49.0 1.0 (1.0) No support No support 8 49.0
Computed property names No support 49.0 34.0 (34) No support No support No support 49.0
Spread operator No support 49.0 34.0 (34) ? ? ? 49.0

[1] Wymaga odblokowanej flagi "Enable experimental Javascript features" w `about:flags`

Notatki specyficzne dla Firefox'a

  • Firefox zapewnił niestandardowe rozszerzenie języka w JS1.7 dla destrukturyzacji. To rozszerzenie zostało usunięte w Gecko 40 (Firefox 40 / Thunderbird 40 / SeaMonkey 2.37). Zobacz błąd 1083498.
  • Poczynając od Gecko 41 (Firefox 41 / Thunderbird 41 / SeaMonkey 2.38) żeby dostosować się do specyfikacji ES2015, składnia destrukturyzacji używająca nawiasów, takia jak([a, b]) = [1, 2]) lub ({a, b}) = { a: 1, b: 2 }, jest teraz uważana za niepoprawną i spowoduje SyntaxError. Zobaczpost Jeffa Waldena oraz błąd 1146136 aby uzyskać więcej informacji.

Zobacz też

Autorzy i etykiety dokumentu

 Autorzy tej strony: danielrakoczy, kdex, grzim
 Ostatnia aktualizacja: danielrakoczy,