JavaScript

Операторы Rest (остаток) и Spread (расширение) можно использовать не только для разделения и соединения отдельных значений массивов. Здесь я собрал 7 малоизвестных способов использования этих операторов.

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

Клонирование объекта с одновременным добавлением дополнительных свойств к клонируемому объекту.

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

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 принимает в качестве аргумента prop. Используя вычисленные имена объектов, 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 к новому объекту перед тем, как расширить object.

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 после операции …object.

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, во время расширения объекта.

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

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

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

8. Бонус. Добавление условных свойств

Вы можете также добавлять условные свойства. В этом примере, 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!' }

Перевод статьи Joel Thoms: 7 Tricks with Resting and Spreading JavaScript Objects