Подписывайтесь на мой твиттер, там всегда что-нибудь интересное!

7 полезных уловок с rest параметрами и spread операторами на JavaScript объектах

7 удобных трюков с rest и spread, которые значительно упростят ваш процесс написания кода.

Перевод 7 Tricks with Resting and Spreading JavaScript Objects

Если у вас есть время, то советую сначала прочитать Оператор spread и rest параметры в JavaScript

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

Ниже вы узнаете 7 малоизвестных трюков с использованием вышеупомянутых операторов в JavaScript.

1. Добавление свойств

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

В этом примере user клонирован и к нему добавлен password в userWithPass.

const user = { id: 100, name: 'Howard Moon'}
const userWithPass = { ...user, password: 'Password!' }

user //=> { id: 100, name: 'Howard Moon' }
userWithPass //=> { id: 100, name: 'Howard Moon', password: 'Password!' }

2. Слияние объектов

Ещё вы можете слить два объекта в один новый.

part1 и part2 сливаются в user1.

const part1 = { id: 100, name: 'Howard Moon' }
const part2 = { id: 100, password: 'Password!' }

const user1 = { ...part1, ...part2 }
//=> { id: 100, name: 'Howard Moon', password: 'Password!' }

Объекты также можно слить и с таким синтаксисом:

const partial = { id: 100, name: 'Howard Moon' }
const user = { ...partial, id: 100, password: 'Password!' }

user //=> { id: 100, name: 'Howard Moon', password: 'Password!' }

3. Исключить свойства объекта

Свойства можно удалить используя деструктуризацию в комбинации с rest оператором. Тут мы деструктуризируем password и остальные свойства объекта отдаются как rest.

const noPassword = ({ password, ...rest }) => rest
const user = {
  id: 100,
  name: 'Howard Moon',
  password: 'Password!'
}

noPassword(user) //=> { id: 100, name: 'Howard moon' }

4. Динамическое исключение свойств

Функция removeProperty берёт props как аргумент. Используя вычисление имен свойств prop может быть исключен динамически из объекта клона.

const user1 = {
  id: 100,
  name: 'Howard Moon',
  password: 'Password!'
}
const removeProperty = prop => ({ [prop]: _, ...rest }) => rest
//                     ----       ------
//                          \   /
//                dynamic destructuring

const removePassword = removeProperty('password')
const removeId = removeProperty('id')

removePassword(user1) //=> { id: 100, name: 'Howard Moon' }
removeId(user1) //=> { name: 'Howard Moon', password: 'Password!' }

5. Организация свойств

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

Чтобы отправить id на первое место, добавьте id: undefined новому объекту перед оператором расширения.

const user3 = {
  password: 'Password!',
  name: 'Naboo',
  id: 300
}

const organize = object => ({ id: undefined, ...object })
//                            -------------
//                          /
//  move id to the first property

organize(user3)
//=> { id: 300, password: 'Password!', name: 'Naboo' }

Чтобы отправить password на последнее место, то сначала деструктуризируйте password из object. Далее, выставьте password за оператором расширения.

const user3 = {
  password: 'Password!',
  name: 'Naboo',
  id: 300
}

const organize = ({ password, ...object }) =>
  ({ ...object, password })
//              --------
//             /
// move password to last property

organize(user3)
//=> { name: 'Naboo', id: 300, password: 'Password!' }

6. Дефолтные свойства

Дефолтные свойства это значения, которые будут выставлены только когда они не включены в оригинальный объект.

В нашем примере user2 не включает в себя quotes. Функция setDefaults проверяет есть ли в объектах quotes, если нет, то он будет выставлен на [].

Вызывая setDefaults(user2), отдающееся значение будет включать в себя quotes: [].

Вызывая setDefaults(user4) ничего не поменяется, потому что user4 уже содержит quotes.

const user2 = {
  id: 200,
  name: 'Vince Noir'
}

const user4 = {
  id: 400,
  name: 'Bollo',
  quotes: ["I've got a bad feeling about this..."]
}

const setDefaults = ({ quotes = [], ...object}) =>
  ({ ...object, quotes })

setDefaults(user2)
//=> { id: 200, name: 'Vince Noir', quotes: [] }

setDefaults(user4)
//=> {
//=>   id: 400,
//=>   name: 'Bollo',
//=>   quotes: ["I've got a bad feeling about this..."]
//=> }

Это также может быть написано таким образом:

const setDefaults = ({ ...object}) => ({ quotes: [], ...object })

7. Переименовывание свойств

Совмещая методики описанные выше, мы можем создать функцию которая переименовывает свойства.

Представьте, что у вас есть несколько объектов с ID в верхнем регистре, которые должны быть в нижнем. Начните с деструктуризации ID из объекта. Далее, верните его в объект как id.

const renamed = ({ ID, ...object }) => ({ id: ID, ...object })

const user = {
  ID: 500,
  name: "Bob Fossil"
}

renamed(user) //=> { id: 500, name: 'Bob Fossil' }

8. БОНУС! Добавляем свойства по условию

Спасибо @vinialbano за то, что указал на то, что вы можете ещё и добавлять свойства в зависимости от условий. В этом примере, password будет добавлен только если password определен.

const user = { id: 100, name: 'Howard Moon' }
const password = 'Password!'
const userWithPassword = {
  ...user,
  id: 100,
  ...(password && { password })
}

userWithPassword //=> { id: 100, name: 'Howard Moon', password: 'Password!' }