扩展运算符(...)用于取出参数对象的所有可遍历属性,拷贝到当前对象之中。
let z = { a: 3, b: 4 }; let n = { ...z }; n // { a: 3, b: 4 }
这等同于使用Object.assign方法。
let aClone = { ...a }; // 等同于 let aClone = Object.assign({}, a);
扩展运算符可以用于合并两个对象。
let ab = { ...a, ...b }; // 等同于 let ab = Object.assign({}, a, b);
如果用户自定义的属性,放在扩展运算符后面,则扩展运算符内部的同名属性会被覆盖掉。
let aWithOverrides = { ...a, x: 1, y: 2 }; // 等同于 let aWithOverrides = { ...a, ...{ x: 1, y: 2 } }; // 等同于 let x = 1, y = 2, aWithOverrides = { ...a, x, y }; // 等同于 let aWithOverrides = Object.assign({}, a, { x: 1, y: 2 });
上面代码中,a对象的x属性和y属性,拷贝到新对象后会被覆盖掉。
这用来修改现有对象部分的部分属性就很方便了。let newVersion = { ...previousVersion, name: 'New Name' // Override the name property };
上面代码中,newVersion对象自定义了name属性,其他属性全部复制自previousVersion对象。
如果把自定义属性放在扩展运算符前面,就变成了设置新对象的默认属性值。let aWithDefaults = { x: 1, y: 2, ...a }; // 等同于 let aWithDefaults = Object.assign({}, { x: 1, y: 2 }, a); // 等同于 let aWithDefaults = Object.assign({ x: 1, y: 2 }, a);
扩展运算符的参数对象之中,如果有取值函数get,这个函数是会执行的。
// 并不会抛出错误,因为 x 属性只是被定义,但没执行 let aWithXGetter = { ...a, get x() { throws new Error('not thrown yet'); } }; // 会抛出错误,因为 x 属性被执行了 let runtimeError = { ...a, ...{ get x() { throws new Error('thrown now'); } } }
如果扩展运算符的参数是null或undefined,这个两个值会被忽略,不会报错。
let emptyObject = { ...null, ...undefined }; // 不报错
.