Перейти к основному содержимому

Объектные свойства rest и spread

· 2 мин. чтения
Матиас Биненс ([@mathias](https://twitter.com/mathias))

Прежде чем обсуждать объектные свойства rest и spread, давайте вспомним очень похожую функцию из прошлого.

ES2015: элементы rest и spread для массивов

Хороший старый ECMAScript 2015 ввел элементы rest для деструктурирующего присваивания массивов и элементы spread для литералов массивов.

// Элементы rest для деструктурирующего присваивания массивов:
const primes = [2, 3, 5, 7, 11];
const [first, second, ...rest] = primes;
console.log(first); // 2
console.log(second); // 3
console.log(rest); // [5, 7, 11]

// Элементы spread для литералов массивов:
const primesCopy = [first, second, ...rest];
console.log(primesCopy); // [2, 3, 5, 7, 11]

ES2018: объектные свойства rest и spread 🆕

Что же нового? _пропоузал добавляет возможность использовать свойства rest и spread для литералов объектов.

// Свойства rest для деструктурирующего присваивания объектов:
const person = {
firstName: 'Себастьян',
lastName: 'Маркбåге',
country: 'США',
state: 'Калифорния',
};
const { firstName, lastName, ...rest } = person;
console.log(firstName); // Себастьян
console.log(lastName); // Маркбåге
console.log(rest); // { country: 'США', state: 'Калифорния' }

<!--truncate-->
// Свойства spread для литералов объектов:
const personCopy = { firstName, lastName, ...rest };
console.log(personCopy);
// { firstName: 'Себастьян', lastName: 'Маркбåге', country: 'США', state: 'Калифорния' }

Свойства spread предлагают более элегантную альтернативу Object.assign() во многих ситуациях:

// Мелкое клонирование объекта:
const data = { x: 42, y: 27, label: 'Сокровище' };
// Старый способ:
const clone1 = Object.assign({}, data);
// Новый способ:
const clone2 = { ...data };
// Оба результата дадут:
// { x: 42, y: 27, label: 'Сокровище' }

// Слияние двух объектов:
const defaultSettings = { logWarnings: false, logErrors: false };
const userSettings = { logErrors: true };
// Старый способ:
const settings1 = Object.assign({}, defaultSettings, userSettings);
// Новый способ:
const settings2 = { ...defaultSettings, ...userSettings };
// Оба результата дадут:
// { logWarnings: false, logErrors: true }

Однако существуют некоторые тонкости в поведении spread относительно сеттеров:

  1. Object.assign() вызывает сеттеры; spread — нет.
  2. Вы можете предотвратить создание собственных свойств в Object.assign() через наследуемые свойства, которые имеют только чтение, но это невозможно сделать с оператором spread.

Статья Акселя Раушмейера объясняет эти особенности более подробно.