Синтаксический сахар для очистки вашей кодовой базы

Синтаксис деструктурирования присваивания - это функция синтаксиса JavaScript, которая была введена в версии JavaScript 2015 года и позволяет нам распаковать список значений массива или пар ключ-значение объекта в отдельные переменные.

Это очень удобно для извлечения записей из массивов или объектов и установки их как значений отдельных переменных. Это очень удобно, потому что альтернативой было получить запись из массива из индекса, а затем установить их как значения переменных для массивов.

Для объектов мы получаем значение из ключа и устанавливаем их как значения переменных.

Разрушение массива

Мы можем легко использовать синтаксис деструктурирующего присваивания в нашем коде. Для массивов мы можем написать:

const [a,b] = [1,2];

Затем мы получаем 1 как значение a и 2 как значение b, потому что деструктивный синтаксис распаковал записи массива в отдельные переменные.

Обратите внимание, что количество элементов в массиве не обязательно должно равняться количеству переменных. Например, мы можем написать:

const [a,b] = [1,2,3]

Тогда a по-прежнему 1, а b по-прежнему 2, потому что синтаксис устанавливает только те переменные, которые перечислены в том же порядке, что и числа, указанные в массиве. Итак, 1 установлено в a, 2 установлено в b, а 3 игнорируется.

Мы также можем использовать оператор rest, чтобы получить оставшиеся переменные, для которых не заданы переменные. Например, мы можем иметь:

const [a,b,...rest] = [1,2,3,4,5,6]

Тогда rest будет [3,4,5,6], в то время как у нас a установлено на 1, а b установлено на 2. Это позволяет нам получить оставшиеся записи массива в переменную, не устанавливая их все в их собственные переменные.

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

const {a,b} = {a:1, b:2};

В приведенном выше коде для a установлено значение 1, а для b установлено значение 2, поскольку ключ соответствует имени переменной при присвоении значений переменным.

Поскольку у нас есть a в качестве ключа и 1 в качестве соответствующего значения, переменная a устанавливается в 1, поскольку имя ключа совпадает с именем переменной. То же самое и с b. У нас есть ключ с именем b со значением 2, поскольку у нас есть переменная с именем b, мы можем установить b на 2.

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

let a, b;
([a, b] = [1, 2]);

Затем у нас a установлено значение 1, а b установлено значение 2, потому что a и b, которые были объявлены, являются теми же самыми назначенными.

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

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

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

Мы также можем установить значения по умолчанию для деструктурирующих назначений. Например:

let a,b;
([a=1,b=2] = [0])

Это допустимый синтаксис. В приведенном выше коде мы получаем, что a равно 0, потому что мы присвоили ему 0. b равно 2, потому что мы ничего ему не присвоили.

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

let a = 1;
let b = 2;
([a,b] = [b,a])

b станет 1, а a станет 2 после последней строки приведенного выше кода. Нам больше не нужно назначать вещи временным переменным, чтобы поменять их местами, и нам также не нужно добавлять или вычитать вещи, чтобы назначать переменные.

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

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

const fn = () =>[1,2]

Мы можем написать:

const [a,b] = fn();

Чтобы получить 1 как a и 2 как b с синтаксисом деструктуризации, потому что возвращаемый массив присваивается переменным с синтаксисом.

Аналогично для объектов мы можем написать:

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

Мы можем игнорировать переменные в середине, пропуская имя переменной в середине деструктурирующего присваивания. Например, мы можем написать:

const fn = () => [1,2,3];
let [a,,b] = fn();

Мы получаем a со значением 1 и b со значением 3, пропуская среднее значение.

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

let [a, ...b,] = [1, 2, 3];

Результатом будет SyntaxError.

Разрушение объекта

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

const {a,b} = {a:1, b:2};

В приведенном выше коде для a установлено значение 1, а для b установлено значение 2, потому что ключ соответствует имени переменной при присвоении значений переменным.

Поскольку у нас есть a в качестве ключа и 1 в качестве соответствующего значения, переменная a установлена ​​в 1, потому что имя ключа совпадает с именем переменной. То же самое и с b. У нас есть ключ с именем b со значением 2, поскольку у нас есть переменная с именем b, мы можем установить b равным 2.

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

const {a: foo, b: bar} = {a:1, b:2};

В приведенном выше коде мы присвоили значение ключа a foo и значение ключа b переменной bar. Нам все еще нужны a и b в качестве ключей на левой стороне, чтобы их можно было сопоставить с теми же именами клавиш на правой стороне для назначения деструктуризации.

Однако a и b на самом деле не определены как переменные. Он просто используется для сопоставления пар "ключ-значение" справа, чтобы их можно было установить в переменные foo и bar.

Назначения деструктуризации с объектами также могут иметь значения по умолчанию. Например, мы можем написать:

let {a = 1, b = 2} = {a: 3};

Затем у нас a установлено значение 3, а b установлено значение 2, что является значением по умолчанию, поскольку у нас не было пары "ключ-значение" с ключом с именем b справа.

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

const {a: foo=3, b: bar=4} = {a:1};

В этом случае foo будет 1, а bar будет 4, потому что мы присвоили левой полосе значение по умолчанию, но присвоили foo 1 с назначением деструктуризации.

Назначение деструктуризации также работает с вложенными объектами. Например, если у нас есть следующий объект:

let user = {
  id: 42,
  userName: 'dsmith',
  name: {
    firstName: 'Dave',
    lastName: 'Smith'
  }
};

Мы можем написать:

let {userName, name: { firstName }} = user;

Чтобы установить displayName на 'dsmith' и firstName на 'Dave'. Поиск выполняется для всего объекта, поэтому, если структура левого объекта такая же, как у правого объекта, и ключи существуют, синтаксис деструктурирующего присваивания будет работать.

Мы также можем использовать синтаксис для распаковки значений в отдельные переменные при передаче объектов в качестве аргументов.

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

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

const who = ({userName, name: { firstName }}) => `${userName}'s first name is ${firstName};
who(user)

Итак, мы получаем userName и firstName, которые будут установлены как 'dsmith' и 'Dave' соответственно, когда мы применили деструктурирующий синтаксис присваивания к аргументу функции who, который является объектом user, который мы определили ранее.

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

const who = ({userName = 'djones', name: { firstName }}) => `${userName}'s first name is ${firstName}`

Если у нас user установлено значение:

let user = {
  id: 42,
  name: {
    firstName: 'Dave',
    lastName: 'Smith'
  }
};

Затем, когда мы вызываем who(user), мы получаем 'djones's first name is Dave', поскольку мы устанавливаем 'djones' как значение по умолчанию для userName.

Мы можем использовать синтаксис деструктурирующего присваивания, когда выполняем итерацию по итеративным объектам. Например, мы можем написать:

const people = [{
    firstName: 'Dave',
    lastName: 'Smith'
  },
  {
    firstName: 'Jane',
    lastName: 'Smith'
  },
  {
    firstName: 'Don',
    lastName: 'Smith'
  },
]
for (let {
    firstName,
    lastName
  } of people) {
  console.log(firstName, lastName);
}

Мы получаем:

Dave Smith
Jane Smith
Don Smith

Регистрируется, поскольку синтаксис деструктуризации работает в for...of циклах, потому что переменная после let является записью массива.

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

let key = 'a';
let {[key]: bar} = {a: 1};

Это установит для bar значение 1, потому что для [key] установлено значение a, а затем интерпретатор JavaScript может сопоставить ключи с обеих сторон и выполнить деструктурирующее присвоение переменной bar.

Это также означает, что ключ слева не обязательно должен быть допустимым именем свойства или переменной. Однако имя переменной после двоеточия слева должно быть допустимым именем свойства или переменной.

Например, мы можем написать:

const obj = { 'abc 123': 1};
const { 'abc 123': abc123 } = obj;

console.log(abc123); // 1

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

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

var obj = {a: 1};
obj.__proto__.b = 2;
const {a, b} = obj;

Мы по-прежнему получаем a равным 1 и b равным 2, поскольку интерпретатор JavaScript ищет b в цепочке наследования прототипов и устанавливает значения, заданные ключом b.

Как мы видим, деструктурирующее присвоение - очень мощный синтаксис. Это экономит время на написание кода для присвоения записей массива переменным или значений объектов в их собственные переменные.

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

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