How can I add a key/value pair to a JavaScript object?
Here is my object literal:
var obj = {key1: value1, key2: value2};
How can I add field key3
with value3
to the object?
There are two ways to add new properties to an object:
var obj = {
key1: value1,
key2: value2
};
Using dot notation:
obj.key3 = "value3";
Using square bracket notation:
obj["key3"] = "value3";
The first form is used when you know the name of the property. The second form is used when the name of the property is dynamically determined. Like in this example:
var getProperty = function (propertyName) {
return obj[propertyName];
};
getProperty("key1");
getProperty("key2");
getProperty("key3");
A real JavaScript array can be constructed using either:
The Array literal notation:
var arr = [];
The Array constructor notation:
var arr = new Array();
Year 2017 answer: Object.assign()
Object.assign(dest, src1, src2, ...) merges objects.
It overwrites dest
with properties and values of (however many) source objects, then returns dest
.
The
Object.assign()
method is used to copy the values of all enumerable own properties from one or more source objects to a target object. It will return the target object.
Live example
var obj = {key1: "value1", key2: "value2"};
Object.assign(obj, {key3: "value3"});
document.body.innerHTML = JSON.stringify(obj);
Year 2018 answer: object spread operator {...}
obj = {...obj, ...pair};
From MDN:
It copies own enumerable properties from a provided object onto a new object.
Shallow-cloning (excluding prototype) or merging of objects is now possible using a shorter syntax than
Object.assign()
.Note that
Object.assign()
triggers setters whereas spread syntax doesn’t.
Live example
It works in current Chrome and current Firefox. They say it doesn’t work in current Edge.
var obj = {key1: "value1", key2: "value2"};
var pair = {key3: "value3"};
obj = {...obj, ...pair};
document.body.innerHTML = JSON.stringify(obj);
Year 2019 answer
Object assignment operator +=
:
obj += {key3: "value3"};
Oops... I got carried away. Smuggling information from the future is illegal. Duly obscured!
I have grown fond of the LoDash / Underscore when writing larger projects.
Adding by obj['key']
or obj.key
are all solid pure JavaScript answers. However both of LoDash and Underscore libraries do provide many additional convenient functions when working with Objects and Arrays in general.
.push()
is for Arrays, not for objects.
Depending what you are looking for, there are two specific functions that may be nice to utilize and give functionality similar to the the feel of arr.push()
. For more info check the docs, they have some great examples there.
_.merge (Lodash only)
The second object will overwrite or add to the base object.
undefined
values are not copied.
var obj = {key1: "value1", key2: "value2"};
var obj2 = {key2:"value4", key3: "value3", key4: undefined};
_.merge(obj, obj2);
console.log(obj);
// → {key1: "value1", key2: "value4", key3: "value3"}
_.extend / _.assign
The second object will overwrite or add to the base object.
undefined
will be copied.
var obj = {key1: "value1", key2: "value2"};
var obj2 = {key2:"value4", key3: "value3", key4: undefined};
_.extend(obj, obj2);
console.log(obj);
// → {key1: "value1", key2: "value4", key3: "value3", key4: undefined}
_.defaults
The second object contains defaults that will be added to base object if they don't exist.
undefined
values will be copied if key already exists.
var obj = {key3: "value3", key5: "value5"};
var obj2 = {key1: "value1", key2:"value2", key3: "valueDefault", key4: "valueDefault", key5: undefined};
_.defaults(obj, obj2);
console.log(obj);
// → {key3: "value3", key5: "value5", key1: "value1", key2: "value2", key4: "valueDefault"}
$.extend
In addition, it may be worthwhile mentioning jQuery.extend, it functions similar to _.merge and may be a better option if you already are using jQuery.
The second object will overwrite or add to the base object.
undefined
values are not copied.
var obj = {key1: "value1", key2: "value2"};
var obj2 = {key2:"value4", key3: "value3", key4: undefined};
$.extend(obj, obj2);
console.log(obj);
// → {key1: "value1", key2: "value4", key3: "value3"}
Object.assign()
It may be worth mentioning the ES6/ ES2015 Object.assign, it functions similar to _.merge and may be the best option if you already are using an ES6/ES2015 polyfill like Babel if you want to polyfill yourself.
The second object will overwrite or add to the base object.
undefined
will be copied.
var obj = {key1: "value1", key2: "value2"};
var obj2 = {key2:"value4", key3: "value3", key4: undefined};
Object.assign(obj, obj2);
console.log(obj);
// → {key1: "value1", key2: "value4", key3: "value3", key4: undefined}
You could use either of these (provided key3 is the acutal key you want to use)
arr[ 'key3' ] = value3;
or
arr.key3 = value3;
If key3 is a variable, then you should do:
var key3 = 'a_key';
var value3 = 3;
arr[ key3 ] = value3;
After this, requesting arr.a_key
would return the value of value3
, a literal 3
.
Performance
Today 2020.01.14 I perform tests on MacOs HighSierra 10.13.6 on Chrome v78.0.0, Safari v13.0.4 and Firefox v71.0.0, for chosen solutions. I divide solutions to mutable (first letter M) and immutable (first letter I). I also provide few immutable solutions (IB,IC,ID/IE) not yet published in answers to this question
Conclusions
- fastest mutable solutions are much faster than fastest immutable (>10x)
- classic mutable approach like
obj.key3 = "abc"
(MA,MB) is fastest - for immutable solutions the
{...obj, key3:'abc'}
andObject.assign
(IA,IB) are fastest - surprisingly there are immutable solutions faster than some mutable solutions for chrome (MC-IA) and safari (MD-IB)
Details
In snippet below there are presended tested solution, you can prefrom test on your machine HERE
var o = {
key1: true,
key2: 3,
};
var log= (s,f)=> console.log(`${s} --> ${JSON.stringify(f({...o}))}`);
function MA(obj) {
obj.key3 = "abc";
return obj;
}
function MB(obj) {
obj['key3'] = "abc";
return obj;
}
function MC(obj) {
Object.assign(obj, {key3:'abc'});
return obj;
}
function MD(obj) {
Object.defineProperty(obj, 'key3', {
value: "abc", // undefined by default
enumerable: true, // false by default
configurable: true, // false by default
writable: true // false by default
});
return obj;
}
function IA(obj) {
return {...obj, key3:'abc'};
}
function IB(obj) {
return Object.assign({key3:'abc'}, obj);
}
function IC(obj) {
let ob= JSON.parse(JSON.stringify(obj))
ob.key3 = 'abc';
return ob;
}
function ID(obj) {
let ob= Object.fromEntries(Object.entries(obj));
ob.key3 = 'abc';
return ob;
}
function IE(obj) {
return Object.fromEntries(Object.entries(obj).concat([['key3','abc']]))
}
log('MA',MA);
log('MB',MB);
log('MC',MC);
log('MD',MD);
log('IA',IA);
log('IB',IB);
log('IC',IC);
log('ID',ID);
log('IE',IE);
This snippet only presents code - it not perform tests itself!