MDN wants to talk to developers like you: https://qsurvey.mozilla.com/s3/8d22564490d8

Деструктурирующее присваивание

Синтаксис деструктурирующего присваивания в выражениях JavaScript позволяет извлекать данные из массивов или объектов при помощи синтаксиса, подобного объявлению массива или литералов в объекте.

Синтаксис

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

({a, b, ...rest} = {a:1, b:2, c:3, d:4}); 
// ES7 - ещё не реализовано Firefox 47a01

Описание

Выражения объявления объектов или массивов предоставляют простой способ создания пакета однородных данных. При создании такого пакета вы получаете возможность использовать его любым доступным образом. Также вы можете возвращать его в функциях.

Одной из ключевых возможностей использования деструктурирующего присваивания является чтение структуры данных одним оператором, хотя помимо этого вы можете найти множество других применений в приведённых ниже примерах.

Данная возможность подобна таковой, присутствующей в языках Perl и Python.

Разбор массивов

Простой пример

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

// без деструктурирования
var one   = foo[0];
var two   = foo[1];
var three = foo[2];

// с деструктурированием
var [one, two, three] = foo;

Обмен значений переменных

После выполнения фрагмента кода, значение b будет 1, a будет 3. Без деструктурирующего присваивания, для обмена значений требуется дополнительная временная переменная (или что-то наподобие XOR-обмена).

var a = 1;
var b = 3;

[a, b] = [b, a];

Возврат нескольких значений

Благодаря деструктурирующему присваиванию, функции могут возвращать несколько значений. Хотя всегда можно было возвращать массивы в функциях, оно предоставляет гибкость:

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

Как вы видите, возвращаемые результаты имеют вид массива, значения которого заключены в квадратные скобки. Вы можете возвращать неограниченное количество результатов таким образом. В следующем примере, f() возвращает [1, 2] как результат:

var a, b;
[a, b] = f();
console.log("A is " + a + " B is " + b);

Оператор [a, b] = f() присваивает результаты функции переменным в квадратных скобках: a будет присвоено 1, b будет присвоено 2.

Вы также можете использовать результат функции в виде массива:

var a = f();
console.log("A is " + a);

В данном случае a будет массивом с элементами 1 и 2.

Игнорирование некоторых значений

Вы также можете проигнорировать не нужные значения:

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

var [a, , b] = f();
console.log("A is " + a + " B is " + b);

После выполнения кода, a будет 1, b будет 3. Значение 2 игнорируется. Таким же образом вы можете игнорировать любые (или все) значения. Например:

[,,] = f();

Получение значений из результата регулярного выражения

Когда метод exec() регулярного выражения находит совпадение, он возвращает массив, содержащий первый совпадающий фрагмент строки и далее группы, определённые в регулярном выражении. Деструктурирующее присваивание упрощает получение данных из этих групп, игнорируя первый фрагмент:

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

var parsedURL = /^(\w+)\:\/\/([^\/]+)\/(.*)$/.exec(url);
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 {p: foo, q: bar} = o;

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

Загрузка модулей

Деструктурирующее присваивание помогает загружать специфичные наборы модулей, как в Add-on SDK:

const { Loader, main } = require('toolkit/loader');

Вложенный объект и разбор массива

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"

Деструктурирование во время обхода

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: 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 из объекта пользователь.

Деструктурирование вычисляемых имён свойств

Вычисляемые имена свойств, например, литералы объектов, могут использоваться при деструктурирующем присваивании:

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

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

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

Спецификация Статус Комментарий
ECMAScript 2015 (6th Edition, ECMA-262)
Определение 'Деструктурирующее присваивание' в этой спецификации.
Стандарт Изначальное определение.

Совместимость с браузерами

Возможность Chrome Firefox (Gecko) Edge Internet Explorer Opera Safari
Базовая поддержка 49.0 2.0 (1.8.1) 14 Нет Нет 7.1
Вычисляемые имена свойств 49.0 34 (34) 14 Нет Нет Нет
Оператор spread 49.0 34 (34) 12[1] ? ? ?
Возможность Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Базовая поддержка Нет Нет 1.0 (1.0) Нет Нет iOS 8
Вычисляемые имена свойств Нет Нет 34.0 (34) Нет Нет Нет
Оператор spread ? ? 34.0 (34) ? ? ?

[1] Необходимо включить "Enable experimental Javascript features" в `about:flags`

Примечания для Firefox

  • Стандартные значения при деструктурирующем присваивании не реализованы: var { x = 3 } = {} и var [foo = "bar"] = []. Смотрите (баг 932080).

Смотрите также

Метки документа и участники

 Внесли вклад в эту страницу: shapkarin, he11b0rn, wa-Nadoo, e-omo, y.ivashchenko, SphinxKnight, dtretyakov
 Обновлялась последний раз: shapkarin,