オブジェクトのレストとスプレッドプロパティについて議論する前に、メモリレーンを旅して、非常に類似した機能を思い出してみましょう。
ES2015 配列のレストとスプレッド要素 #
古き良き ECMAScript 2015 は、配列の非構造化代入用にレスト要素、および配列リテラル用にスプレッド要素を導入しました。
// Rest elements for array destructuring assignment:
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 elements for array literals:
const primesCopy = [first, second, ...rest];
console.log(primesCopy); // [2, 3, 5, 7, 11]
- Chrome: バージョン 47 以降でサポート
- Firefox: バージョン 16 以降でサポート
- Safari: バージョン 8 以降でサポート
- Node.js: バージョン 6 以降でサポート
- Babel: サポート
ES2018: オブジェクトのレストとスプレッドプロパティ 🆕 #
では何が新しいのでしょうか。提案により、オブジェクトリテラルでもレストとスプレッドプロパティが有効になります。
// Rest properties for object destructuring assignment:
const person = {
firstName: 'Sebastian',
lastName: 'Markbåge',
country: 'USA',
state: 'CA',
};
const { firstName, lastName, ...rest } = person;
console.log(firstName); // Sebastian
console.log(lastName); // Markbåge
console.log(rest); // { country: 'USA', state: 'CA' }
// Spread properties for object literals:
const personCopy = { firstName, lastName, ...rest };
console.log(personCopy);
// { firstName: 'Sebastian', lastName: 'Markbåge', country: 'USA', state: 'CA' }
スプレッドプロパティは、多くの状況で Object.assign()
の、よりエレガントな代替手段を提供する
// Shallow-clone an object:
const data = { x: 42, y: 27, label: 'Treasure' };
// The old way:
const clone1 = Object.assign({}, data);
// The new way:
const clone2 = { ...data };
// Either results in:
// { x: 42, y: 27, label: 'Treasure' }
// Merge two objects:
const defaultSettings = { logWarnings: false, logErrors: false };
const userSettings = { logErrors: true };
// The old way:
const settings1 = Object.assign({}, defaultSettings, userSettings);
// The new way:
const settings2 = { ...defaultSettings, ...userSettings };
// Either results in:
// { logWarnings: false, logErrors: true }
ただし、スプレッドがセッターを処理する方法には若干の違いがあります
Object.assign()
はセッターをトリガーするが、スプレッドはトリガーしない。- 継承された読み取り専用プロパティを使用して
Object.assign()
に自身のプロパティを作成させないようにすることはできるが、スプレッド演算子に対してはできない。
Axel Rauschmayer の記事 では、これらの落とし穴をさらに詳しく説明している。
- Chrome: バージョン 60 以降でサポート
- Firefox: バージョン 55 以降でサポート
- Safari: バージョン 11.1 以降でサポート
- Node.js: バージョン 8.6 以降でサポート
- Babel: サポート