Статьи

ES6 в действии: уничтожение заданий

Разрушающее назначение звучит сложно. Это напоминает мне об объектно-ориентированных терминах, таких как инкапсуляция и полиморфизм . Я убежден, что они были выбраны, чтобы простые концепции казались более изощренными

По сути, назначение деструктуризации ECMAScript 6 (ES2015) позволяет извлекать отдельные элементы из массивов или объектов и помещать их в переменные, используя сокращенный синтаксис. Те, кто пришел из PHP, возможно, столкнулись с функцией list () , которая извлекает массивы в переменные за одну операцию. ES6 поднимает это на другой уровень.

Предположим, у нас есть массив:

var myArray = ['a', 'b', 'c'];

Мы можем извлечь эти значения по индексу в ES5:

 var
  one   = myArray[0],
  two   = myArray[1],
  three = myArray[2];

// one = 'a', two = 'b', three = 'c'

Разрушение ES6 допускает более простую и менее подверженную ошибкам альтернативу:

 const [one, two, three] = myArray;

// one = 'a', two = 'b', three = 'c'

Вы можете игнорировать определенные значения, например

 const [one, , three] = myArray;

// one = 'a', three = 'c'

или используйте оператор rest ( ...

 const [one, ...two] = myArray;

// one = 'a', two = ['b, 'c']

Разрушение также работает на объектах, например

 var myObject = {
  one:   'a',
  two:   'b',
  three: 'c'
};

// ES5 example
var
  one   = myObject.one,
  two   = myObject.two,
  three = myObject.three;

// one = 'a', two = 'b', three = 'c'

// ES6 destructuring example
const {one, two, three} = myObject;

// one = 'a', two = 'b', three = 'c'

В этом примере имена переменных onetwothree Мы также можем назначить свойства переменным с любым именем, например

 const myObject = {
  one:   'a',
  two:   'b',
  three: 'c'
};

// ES6 destructuring example
const {one: first, two: second, three: third} = myObject;

// first = 'a', second = 'b', third = 'c'

На более сложные вложенные объекты также можно ссылаться, например,

 const meta = {
  title: 'Destructuring Assignment',
  authors: [
    {
      firstname: 'Craig',
      lastname: 'Buckler'
    }
  ],
  publisher: {
    name: 'SitePoint',
    url: 'http://www.sitepoint.com/'
  }
};

const {
    title: doc,
    authors: [{ firstname: name }],
    publisher: { url: web }
  } = meta;

/*
  doc   = 'Destructuring Assignment'
  name  = 'Craig'
  web   = 'http://www.sitepoint.com/'
*/

Это кажется немного сложным, но помните, что во всех заданиях по деструктуризации:

  • левая часть назначения – цель деструктурирования – шаблон, который определяет назначаемые переменные
  • правая часть присваивания является источником деструктуризации – массивом или объектом, который содержит извлекаемые данные.

Есть ряд других предостережений. Во-первых, вы не можете начать оператор с фигурной скобкой, потому что он выглядит как блок кода, например

 // THIS FAILS
{ a, b, c } = myObject;

Вы должны либо объявить переменные, например,

 // THIS WORKS
const { a, b, c } = myObject;

или используйте скобки, если переменные уже объявлены, например

 // THIS WORKS
({ a, b, c } = myObject);

Вам также следует остерегаться смешивания объявленных и необъявленных переменных, например

 // THIS FAILS
let a;
let { a, b, c } = myObject;

// THIS WORKS
let a, b, c;
({ a, b, c } = myObject);

Это основы деструктуризации. Так когда это будет полезно? Я рад, что ты спросил …

Более легкая декларация

Переменные могут быть объявлены без явного определения каждого значения, например

 // ES5
var a = 'one', b = 'two', c = 'three';

// ES6
const [a, b, c] = ['one', 'two', 'three'];

Следует признать, что деструктурированная версия длиннее. Это немного легче читать, хотя это может быть не так с большим количеством предметов.

Обмен значения переменной

Обмен значениями в ES5 требует временной третьей переменной, но с деструктуризацией это намного проще:

 var a = 1, b = 2;

// ES5 swap
var temp = a;
a = b;
b = temp;

// a = 2, b = 1

// ES6 swap back
[a, b] = [b, a];

// a = 1, b = 2

Вы не ограничены двумя переменными; можно изменить любое количество элементов, например,

 // rotate left
[b, c, d, e, a] = [a, b, c, d, e];

Параметры функции по умолчанию

Предположим, у нас была функция для вывода нашего meta

 var meta = {
  title: 'Destructuring Assignment',
  authors: [
    {
      firstname: 'Craig',
      lastname: 'Buckler'
    }
  ],
  publisher: {
    name: 'SitePoint',
    url: 'http://www.sitepoint.com/'
  }
};

prettyPrint(meta);

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

 // ES5 default values
function prettyPrint(param) {
  param = param || {};
  var
    pubTitle = param.title || 'No title',
    pubName = (param.publisher && param.publisher.name) || 'No publisher';

  return pubTitle + ', ' + pubName;
}

В ES6 мы можем назначить значение по умолчанию для любого параметра, например

 // ES6 default value
function prettyPrint(param = {}) {

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

 // ES6 destructured default value
function prettyPrint(
  {
    title: pubTitle = 'No title',
    publisher: { name: pubName = 'No publisher' }
  } = {}
) {
  return pubTitle + ', ' + pubName;
}

Я не уверен, что это легче читать, но это значительно короче.

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

Функции могут возвращать только одно значение, но это может быть сложный объект или многомерный массив. Разрушение назначения делает это более практичным, например,

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

const [a, b, c] = f();

// a = 1, b = 2, c = 3

Для итерации

Рассмотрим массив книжной информации:

 const books = [
  {
    title: 'Full Stack JavaScript',
    author: 'Colin Ihrig and Adam Bretz',
    url: 'http://www.sitepoint.com/store/full-stack-javascript-development-mean/'
  },
  {
    title: 'JavaScript: Novice to Ninja',
    author: 'Darren Jones',
    url: 'http://www.sitepoint.com/store/leaern-javascript-novice-to-ninja/'
  },
  {
    title: 'Jump Start CSS',
    author: 'Louis Lazaris',
    url: 'http://www.sitepoint.com/store/jump-start-css/'
  },
];

ES6 for-of аналогичен for-in

 for (const b of books) {
  console.log(b.title + ' by ' + b.author + ': ' + b.url);
}

Деструктурирующее назначение обеспечивает дальнейшие улучшения, например

 for (const {title, author, url} of books) {
  console.log(title + ' by ' + author + ': ' + url);
}

Обработка регулярных выражений

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

 const [a, b, c, d] = 'one two three'.match(/\w+/g);

// a = 'one', b = 'two', c = 'three', d = undefined

Поддержка деструктурирующих заданий

Деструктурирующее задание может не революционизировать вашу жизнь в процессе разработки, но может сэкономить некоторые значительные печатные усилия!

В настоящее время поддержка деструктурирующего назначения хорошая. Он доступен в Node и во всех основных браузерах, за исключением Internet Explorer. Если вам требуется поддержка старых браузеров, рекомендуется использовать компилятор, такой как Babel или Traceur , который преобразует назначения деструктурирования ES6 в эквивалент ES5.