--- title: Деструктуризація slug: Web/JavaScript/Reference/Operators/Destructuring_assignment tags: - Destructuring - ECMAScript 2015 - JavaScript - Operator - Деструктуризація - Оператор translation_of: Web/JavaScript/Reference/Operators/Destructuring_assignment original_slug: Web/JavaScript/Reference/Operators/Деструктуризація ---
{{jsSidebar("Operators")}}

Деструктуризація (деструктуризаційне присвоєння) - JavaScript вираз, який дозволяє витягувати дані з масивів та об’єктів в окремі змінні.

Синтаксис

var a, b, rest;
[a, b] = [10, 20];
console.log(a); // 10
console.log(b); // 20

[a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(a); // 10
console.log(b); // 20
console.log(rest); // [30, 40, 50]

({a, b} = {a: 10, b: 20});
console.log(a); // 10
console.log(b); // 20

// Експерементальний синтаксис (ще не стандартизований)
({a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40});

Опис

Вирази присвоєння літералів об’єктів та масивів надають простий спосіб створювати ad hoc (ад-гок) структури даних.

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

Деструктуризаційне присвоєння використовує подібний синтаксис, де ліва сторона виразу визначає елементи, що потрібно витягнути зі змінної-джерела (правої сторони).

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

Це подібне до способів, що доступні у мовах програмування на кшталт Perl та Python.

Деструктуризація масивів

Звичайне присвоєння

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

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

Присвоєння, окреме від оголошення

Значення може бути присвоєне змінній окремо від оголошення цієї змінної.

var a, b;

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

Значення за промовчанням

Змінній може бути присвоєне значення за промовчанням у випадку, коли витягнуте значення є undefined.

var a, b;

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

Обмін змінних

Дві змінні можуть обмінятися значеннями за допомогою одного деструктуризаційного виразу. 

Без деструктуризації, обмін двох значеннь потребує тимчасової змінної (або в деяких низькорівневих мовах XOR-обміну).

var a = 1;
var b = 3;

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

Розбір масиву, поверненого з функції

Завжди було можливо повернути масив із функції. Деструктуризація може зробити обробку повернутого масиву більш виразною.

У цьому прикладі f() повертає значення [1, 2], які можуть бути розібрані одним рядком коду за допомогою деструктуризації.

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

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

Пропуск деяких значень

Можна пропустити повернуті значення, які тобі не цікаві:

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

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

Також можна пропустити всі значення (але навіщо?):

[,,] = f();

Присвоєння решти масиву змінній

Деструктуризуючи масив, можна присвоїти змінній решту його елементів за допомогою оператора розпакування:

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

Зауваж, що буде видана помилка {{jsxref("SyntaxError")}}, якщо поставити прикінцеву кому в лівій частині виразу за елементом решти:

var [a, ...b,] = [1, 2, 3];
// SyntaxError: елемент решти не може мати прикінцевої коми

Витягнення значеннь з масиву збігів регулярного виразу

Коли метод регулярного виразу exec() знаходить збіг, він повертає масив, що містить першим елементом повністю відповідну частину рядку, а далі частини рядку, що збіглися з кожною взятою в дужки групою в регулярному виразі. Деструктуризаційне присвоєння дозволяє з легкістю витягувати частини цього масиву, пропускаючи повний збіг, якщо він не потрібний.

var url = 'https://developer.mozilla.org/en-US/Web/JavaScript';

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

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

console.log(protocol); // "https"

Деструктуризація об’єктів

Звичайне присвоєння

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

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

Присвоєння, окреме від оголошення

Значення може бути присвоєне змінній окремо від оголошення цієї змінної.

var a, b;

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

Дужки ( .. ) навколо виразу присвоєння необхідні при деструктуризаційному присвоєні об’єкта без оголошення.

Вираз {a, b} = {a: 1, b: 2} сам по собі є синтаксично неправильним, оскільки {a, b} в лівій його частині розглядається як блок коду, а не як об’єкт.

Проте, ({a, b} = {a: 1, b: 2}) є правильним, як і var {a, b} = {a: 1, b: 2}

Присвоєння новим змінним

Значення може бути отримане з об’єкту та присвоєне змінній з іменем, інакшим від назви властивості об’єкта.

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

console.log(foo); // 42
console.log(bar); // true  

Значення за промовчанням

Змінній може бути присвоєне значення за промовчанням у випадку, коли витягнуте значення з об’єкту є undefined.

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

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

Встановлення значення за промовчанням аргументам функції

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);
  // тепер, врешті, малюй діаграму
}

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

ES2015 версія

function drawES2015Chart({size = 'big', cords = {x: 0, y: 0}, radius = 25} = {}) {
  console.log(size, cords, radius);
  // малюй діаграму
}

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

Вкладена деструктуризація об’єктів та масивів

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"

For of цикл та деструктуризація

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"

Витягнення полів з об’єктів, що передані аргументами в функцію

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"

Це витягує id, displayName та firstName з об’єкта user та виводить їх.

Розраховувані імена властивостей об’єкта та деструктуризація

Розраховувані імена властивостей об’єкта можуть також бути використані разом із деструктуризацією

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

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

Специфікації

Specification Status Comment
{{SpecName('ES2015', '#sec-destructuring-assignment', 'Destructuring assignment')}} {{Spec2('ES2015')}} Initial definition.
{{SpecName('ESDraft', '#sec-destructuring-assignment', 'Destructuring assignment')}} {{Spec2('ESDraft')}}  

Сумісність з браузерами 

{{CompatibilityTable}}
Feature Chrome Firefox (Gecko) Edge Internet Explorer Opera Safari
Basic support {{CompatChrome(49.0)}} {{ CompatGeckoDesktop("1.8.1") }} 14 {{CompatNo}} {{CompatNo}} 7.1
Computed property names {{CompatChrome(49.0)}} {{ CompatGeckoDesktop("34") }} 14 {{CompatNo}} {{CompatNo}} {{CompatNo}}
Spread operator {{CompatChrome(49.0)}} {{ CompatGeckoDesktop("34") }} 12[1] {{CompatUnknown}} {{CompatUnknown}} {{CompatUnknown}}
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile Chrome for Android
Basic support {{CompatNo}} {{CompatChrome(49.0)}} {{ CompatGeckoMobile("1.0") }} {{CompatNo}} {{CompatNo}} 8 {{CompatChrome(49.0)}}
Computed property names {{CompatNo}} {{CompatChrome(49.0)}} {{ CompatGeckoMobile("34") }} {{CompatNo}} {{CompatNo}} {{CompatNo}} {{CompatChrome(49.0)}}
Spread operator {{CompatNo}} {{CompatChrome(49.0)}} {{ CompatGeckoMobile("34") }} {{CompatUnknown}} {{CompatUnknown}} {{CompatUnknown}} {{CompatChrome(49.0)}}

[1] Потребує ввімкнення "Enable experimental Javascript features" в налаштуваннях `about:flags`

Примітки для Firefox

Дивись також