There are several ways to do this. Below I will list three different cases.
Use the scattering syntax (Operator spread)
If you are in an environment that the support, you can use the scattering syntax, also known as Operator spread, in literal objects. It works like this:
const obj1 = { foo: 'A', bar: 'B' };
const obj2 = { baz: 'C' /* ... */ };
const newObj = { ...obj1, ...obj2 };
console.log(newObj);
Basically, in the example above, we are creating a new object, newObj
, through scattering syntax. Basically, with this:
{ ...obj1, ...obj2 }
// ↑
// Entenda isso como a criação de um novo objeto. Por isso `obj1` e `obj2` não
// são alterados.
We are programming the creation of a new object, whose properties will be derived from the spreading of obj1
and obj2
. In that case, obj1
and obj2
nay will have its properties modified, since we are creating a new literal.
Note that you can create an object with the spread properties and new properties as well. So:
const oldObj = {
foo: 'A'
};
const newObj = {
...oldObj,
bar: 'B',
baz: 'C'
};
console.log(newObj);
Object.assign
You can also use the Object.assign
, which is a little more supported than scattering syntax. So:
const obj1 = { foo: 'A', bar: 'B' };
const obj2 = { baz: 'C' /* ... */ };
const newObj = Object.assign({}, obj1, obj2);
console.log(newObj);
Note that in the method assign
, i put a new object literal in the first argument. I did this because this method will change the reference you pass in the first argument:
const obj1 = { foo: 'A', bar: 'B' };
const obj2 = { baz: 'C' /* ... */ };
Object.assign(obj1, obj2);
console.log('Objeto 1', obj1);
console.log('Objeto 1', obj2);
The very documentation of Object.assign
names the first argument as target
. This is because, as I explained above, the reference you give to it will be changed. So it’s useful to pass a new object if you don’t want it to happen.
Other implementations (for environments ancient)
If you want to support environments that don’t have these new features, introduced in recent specifications of Ecmascript, there are still ways (a little less trivial) to do this. One of them is to use a loop for..in
, iterates over the enumerated properties of an object. So, you can do something like this:
// Irá retornar um **novo** objeto, a partir da união dos argumentos.
function merge() {
'use strict';
// Note que criamos um novo objeto. Assim nenhum objeto
// passado será alterado. :)
var newObj = {};
for (var i = 0; i < arguments.length; i++) {
// `arguments`:
var currentObj = arguments[i];
for (var key in currentObj) {
// `hasOwnProperty`:
if (Object.prototype.hasOwnProperty.call(currentObj, key)) {
newObj[key] = currentObj[key];
}
}
}
return newObj;
}
var obj1 = { foo: 'A', bar: 'B' };
var obj2 = { baz: 'C' };
var obj3 = { qux: 'D' };
var newObj = merge(obj1, obj2, obj3);
console.log(newObj);
The previous implementation of the function merge
uses some language features that are very little used:
- The
arguments
Object was used, since the function merge
was implemented in order to accept multiple arguments (such as merge(a, b, c, d, ... n)
). So I used arguments
, since modern resources such as Operator spread, which are used to do this in environments that support new Ecmascript specifications, are not available.
- The method
hasOwnProperty
was used to ensure that only properties of the past object are joined together. This will exclude properties inherited by prototype
.
- The statement
var
was used, since let
and const
would not be available in that hypothetical environment. Directive 'use strict'
was also used in this sense.
You can do that using the
Array.prototype.concat()
– Jakson Fischer
I tried, but I made that mistake:
Uncaught TypeError: objeto1.concat is not a function
 at <anonymous>:1:25
– Arthur Siqueira
Can provide a [mcve] of how you did this concatenation that generated error?
– Augusto Vasques