"use strict"; Object.defineProperty(Object.prototype, 'NOSET', { get(value) { // noop }, }); Object.defineProperty(Object.prototype, 'NOWRITE', { writable: false, value: 'abc', }); const obj = { NOSET: 123 }; // this wouldn't work as expected if transformed as Object.assign (or equivalent) // because those trigger object setters (spread don't) const objSpread = { ...obj }; expect(objSpread).toHaveProperty('NOSET', 123); const obj2 = { NOWRITE: 456 }; // this line would throw `TypeError: Cannot assign to read only property 'NOWRITE'` // if transformed as Object.assign (or equivalent) because those use *assignment* for creating properties // (spread defines them) const obj2Spread = { ...obj2 }; expect(obj2Spread).toHaveProperty('NOWRITE', 456); const KEY = Symbol('key'); const obj3Spread = { ...{ get foo () { return 'bar' } }, [KEY]: 'symbol' }; expect(Object.getOwnPropertyDescriptor(obj3Spread, 'foo').value).toBe('bar'); expect(Object.getOwnPropertyDescriptor(obj3Spread, KEY).value).toBe('symbol'); const obj4Spread = { ...Object.prototype }; expect(Object.getOwnPropertyDescriptor(obj4Spread, 'hasOwnProperty')).toBeUndefined(); expect(() => ({ ...null, ...undefined })).not.toThrow(); const o = Object.create(null); o.a = 'foo'; o.__proto__ = []; const o2 = { ...o }; expect(Array.isArray(Object.getPrototypeOf(o2))).toBe(false);