How to fully copy / overwrite an object using Object.assign()?
If there would be another approach, it would be highly appreciated. :)
The purpose is to update the existing object to its new value.
Below is my code snippet and the expected result should be the same as the value of object2 only.
Expected result: { a: 8, b: 7 }
const object1 = {
a: 1,
b: 2,
c: {
d: 3
}
};
const object2 = {
a: 8,
b: 7
};
Object.assign(object1, object2);
console.log(object1);
For keeping the same object reference, you could remove all properties in advance and then assign the wanted properties with Object.assign.
const object1 = { a: 1, b: 2, c: { d: 3 } };
const object2 = { a: 8, b: 7 };
Object.assign(
Object.keys(object1).reduce((o, k) => (Reflect.deleteProperty(o, k), o), object1),
object2
);
console.log(object1);
IE
var object1 = { a: 1, b: 2, c: { d: 3 } },
object2 = { a: 8, b: 7 };
Object.keys(object2).reduce(
function (object, key) {
object[key] = object2[key];
return object;
},
Object.keys(object1).reduce(function (object, key) {
delete object[key];
return object;
}, object1)
);
console.log(object1);
If you want to override the object1 properties with those from object2, you need to do it like this:
object1 = Object.assign({}, object2);
But with this you need to declare object1 with var keyword so you can assign a new value to it.
Demo:
var object1 = {
a: 1,
b: 2,
c: {
d: 3
}
};
const object2 = {
a: 8,
b: 7
};
object1 = Object.assign({}, object2);
console.log(object1);
Related
function extend(obj1, obj2) {
var obj2Keys = Object.keys(obj2);
var obj2Values = Object.values(obj2);
var obj1Keys = Object.keys(obj1);
var obj1Values = Object.keys(obj1);
var newObj = {};
for(var i=0; i<obj1Keys.length; i++) {
if(obj1Keys[i] !== obj2Keys[i]) {
}
}
}
var obj1 = {
a: 1,
b: 2
};
var obj2 = {
b: 4,
c: 3
};
extend(obj1, obj2);
console.log(obj1); // --> {a: 1, b: 2, c: 3}
console.log(obj2); // --> {b: 4, c: 3}
/*
1. Add any keys that are not in the 1st object.
2. If the 1st object already has a given key, ignore it (do not
overwrite the property value).
3. Do not modify the 2nd object at all.
*/
Hey guys, trying to figure this one out. I'm sure i'm doing this the most inefficient way. I'm struggling to compare indexes of these objects.. Any help?? I was using for in loops originally but I couldn't conceptually understand what I was doing lol. Kinda stuck at this point.
const firstObject = {a:1,b:2,c:3}
const secondObject = {a:11,b:22,c:33,d:44}
var newObject = {...secondObject,...firstObject}
console.log(newObject)
result:
{"a":1,"b":2,"c":3,"d":44}
Get keys of obj2
Iterate over them using the for-loop
In each iteration, if obj1 does not have this key, and the record to it from obj2
function extend (obj1, obj2) {
const obj2Keys = Object.keys(obj2);
for(let i = 0; i < obj2Keys.length; i++) {
const currentKey = obj2Keys[i]
if(!obj1[currentKey]) {
obj1[currentKey] = obj2[currentKey];
}
}
}
const obj1 = { a: 1, b: 2 }; const obj2 = { b: 4, c: 3 };
extend(obj1, obj2);
console.log(obj1); // --> {a: 1, b: 2, c: 3}
console.log(obj2); // --> {b: 4, c: 3}
Another way using .forEach:
function extend (obj1, obj2) {
Object.keys(obj2).forEach(currentKey => {
if(!obj1[currentKey]) {
obj1[currentKey] = obj2[currentKey];
}
});
}
const obj1 = { a: 1, b: 2 }; const obj2 = { b: 4, c: 3 };
extend(obj1, obj2);
console.log(obj1); // --> {a: 1, b: 2, c: 3}
console.log(obj2); // --> {b: 4, c: 3}
Use the spread syntax to combine the objects. The spread syntax basically inserts the objects key/value pairs wherever you write it, so you're creating a new object with {...obj1, ...obj2}. If there are pairs with duplicate keys, the pair from the second object will be selected.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
let obj1 = {a: 1, b: 2}
let obj2 = {b: 4, c: 3}
let obj3 = {...obj2, ...obj1}
console.log(obj3)
I am trying to transfer/copy properties from object1 to object2, but only properties that are undefined in object2.
Thanks in advance, I hope this comes across clearly!
let object1 = { a: 1, b: 2, c: 3, d: 4 }
let object2 = { a: 'string' }
fillObj = function (object2, object1) {
for (let key in object1) {
if (typeof object2.key === undefined) {
object2[key] = object1[key];
}
}
return object2; //should return {a: 'string', b: 2, c: 3, d: 4 }
};
(1) Look properties on an object by a variable property name by using bracket notation, not dot notation
(2) To check if something is undefined, either compare against undefined directly, or use typeof and compare against the string 'undefined' (but this check isn't needed for this algorithm)
(3) Make sure the properties are own properties, not inherited properties, with hasOwnProperty
let object1 = { a: 'string' }
let object2 = { a: 1, b: 2, c: 3, d: 4 }
fillObj = function (object2, object1) {
for (let key in object1) {
if (object1.hasOwnProperty(key)) {
object2[key] = object1[key];
}
}
return object2; //should return {a: 'string', b: 2, c: 3, d: 4 }
};
console.log(fillObj(object2, object1));
Or use Object.entries, which iterates over own-properties only:
let object1 = { a: 'string' }
let object2 = { a: 1, b: 2, c: 3, d: 4 }
fillObj = function (object2, object1) {
for (const [key, val] of Object.entries(object1)) {
object2[key] = val;
}
return object2; //should return {a: 'string', b: 2, c: 3, d: 4 }
};
console.log(fillObj(object2, object1));
As always I will explain my problem by example (that I solved but its a lot of code and its ugly, that's why I'm looking for a better solution). I'm trying to look at an object like this:
const object1 = {
a: {a:1},
b: 2,
c: 3,
d: 4,
};
I want to check if this object has any of the following properties [a,f] and if have one of them to create a new object with these properties
const object2 = {
a: {a:1},
};
const object1 = {
a: {a:1},
b: 2,
c: 3,
d: 4,
}
const arrOfItem = ['a', 'd']
const newObj = {}
for(let item in object1) {
if(arrOfItem.includes(item)) {
newObj[item]= object1[item]
}
}
console.log(newObj)
see if this works for you,
function makeObject (properties) {
const originalObject = {
a: {a:1},
b: 2,
c: 3,
d: 4,
};
let newObject = {}
properties.forEach(property => {
if(originalObject.hasOwnProperty(property)) {
newObject[property] = originalObject[property];
}
});
return newObject;
}
pass the properties as an array of strings to makeObject function
const d = ['a', 'f', 'd']
const object1 = {
a: {a:1},
b: 2,
c: 3,
d: 4,
};
const object2 = d.reduce((acc, ele) => {
if(object1[ele] !== undefined) acc[ele] = object1[ele];
return acc;
}, {});
console.log(object2);
Let's assume I have two simple objects and I want to create a third one that will be joining their properties. This works perfectly:
(()=>{
const a1 = {a: 2, b: 3}
const b1 = {a: 100, c: 5}
return {...a1, ...b1}
})()
// { a: 100, b: 3, c: 5 }
But it stops working once I try to create a new object derived from b1 using .reduce. For a sake of simplicity let's create a reduce function that simply makes a shallow copy of the b1 object:
let r = (()=>{
const a1 = {a: 2, b: 3}
const b1 = {a: 100, c: 5},
b2 = Object.entries(b1).reduce((acc, [key, value])=>Object.defineProperty(acc, key, {value}), {})
console.log(b2) // {a: 100 c: 5}
return {...a1, ...b2}
})()
console.log(r);// { a: 2, b: 3 }
I have a feeling that there is something about .reduce function that I just don't understand. What can I do to fix this?
By default, properties created with defineProperty are not enumerable, so they won't be included with a spread.
To fix:
b2 = Object.entries(b1).reduce((acc, [key, value]) =>
Object.defineProperty(acc, key, {value, enumerable: true})
, {})
You should mark the property as enumerable
Object.defineProperty(acc, key, {value, enumerable: true});
Why not just using the function Object.assign instead, it's straightforward.
let r = (()=> {
const a1 = {a: 2, b: 3};
const b1 = {a: 100, c: 5};
const b2 = Object.entries(b1).reduce((acc, [key, value]) => Object.assign(acc, {[key]: value}), {})
console.log(b2); // {a: 100 c: 5}
return {...a1, ...b2}
})()
console.log(r); // { a: 2, b: 3 }
One fix could be to use Object.assign to create a copy of b1 like:
let r = (()=>{
const a1 = {a: 2, b: 3}
const b1 = {a: 100, c: 5}
const b2 = Object.assign({}, b1)
console.log(b2) // {a: 100 c: 5}
return {...a1, ...b2}
})()
console.log(r); // { a: 100, b: 3, c: 5 }
How to know what the first param in $.extend does? It says deep copy but what does it means?
I try it but it doesn't shows any different in the result
http://jsfiddle.net/rvbrw0p9/
$(document).ready(function() {
var object1 = { a: 1, b: 2, c: 3 };
var object2 = { a: 'a', b: 2, c: 'c'};
var r = $.extend(object1 , object2 );
var r2 = $.extend(true, object1 , object2 );
console.log(r);
console.log(r2);
});
Technically there is no different from r and r2.
But please take note on the $.extend() behaviour http://api.jquery.com/jQuery.extend/
NOTE 1 jQuery.extend( target [, object1 ] [, objectN ] )
var r = $.extend(object1 , object2 );
// mean now we merge object2 into object1 so object1={ a: 'a', b: 2, c: 'c'}
console.log(object1) // return { a: 'a', b: 2, c: 'c'}
console.log(r) // return { a: 'a', b: 2, c: 'c'}
NOTE 2 jQuery.extend( [deep ], target, object1 [, objectN ] )
var objA = { k: 1, b: 2};
var objB = { k: 2, b: 'b', z:9};
var ret = $.extend(true, objA, objB); // when true as first parameter = merge recursive (deep copy)
console.log(objA); // return { k: 2, b: 'b', z:9}
console.log(ret); // return { k: 2, b: 'b', z:9}
NOTE 3 What happen if we pass False or {} as first param.
var objA = { k: 1, b: 2};
var objB = { k: 2, b: 'b', z:9};
var ret = $.extend(false, objA, objB);
console.log(objA) // return { k: 1, b: 2}
console.log(ret) // return { k: 2, b: 'b', z:9}
From the above example we can see True deep copy will update target value accordingly by other objectN value