在 ECMAScript 2016 中,新增了一种称为对象展开运算符的语法。该语法能够方便地展开对象并将其合并到另一个对象中,大大简化了一些常见的对象操作,特别是在前端开发中经常使用的操作。
对象展开语法
对象展开运算符使用 “...” 来表示,可以出现在函数调用、数组字面量、对象字面量等各种地方。在对象字面量中,展开运算符可以将一个对象的所有属性和值都合并到另一个对象中,如下所示:
const obj1 = { a: 1, b: 2 }; const obj2 = { ...obj1, c: 3, d: 4 }; console.log(obj2); // { a: 1, b: 2, c: 3, d: 4 }
在上面的例子中,我们使用对象展开运算符将 obj1 对象的所有属性和值都合并到 obj2 中,并加上了 c 和 d 两个新的属性。这个操作等价于如下代码:
const obj1 = { a: 1, b: 2 }; const obj2 = Object.assign({}, obj1, { c: 3, d: 4 }); console.log(obj2); // { a: 1, b: 2, c: 3, d: 4 }
上面的代码使用 Object.assign() 来实现合并操作。但是,对象展开运算符更加简洁,并且可以更好地表达出合并的语义。
对象展开的限制
需要注意的是,对象展开运算符只能展开可枚举属性,也就是 enumerable 为 true 的属性。这意味着如果你想展开一个对象的原型链中的属性,你必须将这些属性设置为可枚举的。例如:
const obj1 = { a: 1, b: 2 }; const obj2 = { ...obj1, toString() { return 'hello'; } }; console.log(obj2); // { a: 1, b: 2, toString: [Function: toString] }
在上面的例子中,我们在 obj2 中添加了一个 toString() 方法,但是由于 toString() 是 Object 的原型链上的方法,它默认是不可枚举的。因此,如果我们现在尝试通过展开运算符将 obj1 中的属性合并到 obj2 中,我们将会发现 toString() 方法并没有被合并进来。为了避免这种情况,我们需要将 toString() 方法设置为可枚举:
const obj1 = { a: 1, b: 2 }; Object.defineProperty(obj1, 'toString', { value() { return 'hello'; }, enumerable: true }); const obj2 = { ...obj1 }; console.log(obj2); // { a: 1, b: 2, toString: [Function: toString] }
对象展开的应用场景
对象展开运算符有很多应用场景,在前端开发中也经常会用到。下面是一些例子:
复制一个对象
如果你想复制一个对象,你可以使用对象展开运算符来达到这个目的:
const obj1 = { a: 1, b: 2 }; const obj2 = { ...obj1 }; console.log(obj2); // { a: 1, b: 2 }
合并多个对象
你可以使用对象展开运算符来方便地将多个对象合并成一个:
const obj1 = { a: 1 }; const obj2 = { b: 2 }; const obj3 = { c: 3 }; const obj4 = { ...obj1, ...obj2, ...obj3 }; console.log(obj4); // { a: 1, b: 2, c: 3 }
更新一个对象的属性
你可以使用对象展开运算符来更新一个对象的属性:
const obj1 = { a: 1, b: 2 }; const obj2 = { ...obj1, b: 3 }; console.log(obj2); // { a: 1, b: 3 }
在上面的例子中,我们使用对象展开运算符来更新 obj1 中的 b 属性。
总结
ECMAScript 2016 中新增的对象展开运算符语法,可以方便地展开对象并将其合并到另一个对象中。这个语法简化了一些常见的对象操作,特别是在前端开发中经常使用的操作。需要注意的是,对象展开运算符只能展开可枚举属性,也就是 enumerable 为 true 的属性。如果你尝试展开对象的原型链中的属性,你必须将这些属性设置为可枚举的。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64564c0a968c7c53b097ee42