Object.assign merges enumerable own properties from one or more source objects into a target object and returns that target. It builds objects by copying property values rather than linking them through a prototype chain, making it useful for composing independent pieces of data or behavior. section 1.2 section 3.3.1
Its behavior is simple but has important boundaries:
- Copies only properties owned directly by each source; inherited properties are ignored. section 3.3.1
- Copies only enumerable properties; non-enumerable properties are skipped. section 3.3.1
- Processes sources from left to right, so a later source overrides an earlier value with the same property name. section 3.3.1
- Performs a shallow copy, so nested values remain shared references rather than being recursively cloned. section 3.3.1
- Assigns into the target: existing properties use the internal [[Set]] operation, which can invoke setters. section 3.3.2
Defaults and composition
Use an empty object when you want a new result, or use a defaults object as the target when configuring an operation: function doSomething(config = {}) { return Object.assign({ foo: 'foo', bar: 'bar' }, config); } Object.assign({}, { a: 'a' }, { b: 'b' }); // { a: 'a', b: 'b' } Object.assign({}, { a: 'a' }, { a: 'ca', c: 'c' }); // { a: 'ca', c: 'c' } For mixins, later objects provide the winning implementation. Combining AquaticAnimal before TerrestrialAnimal therefore selects the latter object's breathe method. section 3.4.2

