在讨论对象剩余和展开属性之前,让我们回顾一下过去,回忆一下一个非常类似的功能。
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: 支持