I am interested in to assign values to only those keys that are available in destination object from source object.
const destination= {
name: "John Doe",
age: 24,
}
const source= {
name: "Usman Khan",
age: 36,
title: "Full stack developer",
location: "Remote"
}
if I use Object.assign it merges both object same with the spread operator.
I am only interested to assign values to keys available in destination object i.e. Only Name and age, not to merge the two objects without loops and if conditions or any other efficient method.
CodePudding user response:
You still need some iterations.
const
getProperty = object => key => ({ [key]: object[key] }),
destination= { name: "John Doe", age: 24 },
source= { name: "Usman Khan", age: 36, title: "Full stack developer", location: "Remote" };
Object.assign(
destination,
...Object
.keys(destination)
.map(getProperty(source))
);
console.log(destination);
CodePudding user response:
This can be done using Object.entries()
and a forEach
loop along with the in
operator.
Object.entries()
gives you an array of entries [key,value]
in the object.
const destination= {
name: "John Doe",
age: 24,
};
const source= {
name: "Usman Khan",
age: 36,
title: "Full stack developer",
location: "Remote"
};
Object.entries(source).forEach( ([key,value]) => {
if(key in destination) destination[key] = value;
});
console.log(destination);
console.log(source);
CodePudding user response:
Iterate over destination
using for...in
, while checking if every property is in source
using Object#hasOwnProperty
to update its value.
const
destination = { name: "John Doe", age: 24 },
source = { name: "Usman Khan", age: 36, title: "Full stack developer", location: "Remote" };
for(const prop in destination) {
if(source.hasOwnProperty(prop)) {
destination[prop] = source[prop];
}
}
console.log(destination);
CodePudding user response:
This problem can be reduced to:
- Find properties that exist on both
destination
andsource
. - Assign these properties from
source
todestination
.
Here is an example implementation:
const destination = { name: "John Doe", age: 24 };
const source = {
name: "Usman Khan",
age: 36,
title: "Full stack developer",
location: "Remote"
};
console.log(assignExisting(destination, source));
function assignExisting(destination, source) {
const sourceKeys = allKeys(source);
for (const key in destination) {
if (sourceKeys.includes(key)) { // If in both destination and source
destination[key] = source[key]; // then assign property
}
}
return destination;
}
function allKeys(o) { // See excursus for why I use this
const keys = [];
for (const p in o) keys.push(p);
return keys;
}
Excursus: Prototypes, properties and delete
JavaScript is prototype-based, which means that objects are or may have prototypes. Since prototypes are objects themselves, they naturally can have properties as well.
When an object and a prototype of it have a property of similar name, the object's property shadows the prototype's property. This does not override the prototype's property.
This means an object can have own properties and inherited properties. To find whether a property is an object's own, you can use Object.prototype.hasOwnProperty()
.
Simply assigning undefined
to an object's property will however not delete it: It will still shadow the prototype's properties. To actually delete a property, use the delete
operator:
function ExampleObject() {}
ExampleObject.prototype.value = "inherited";
const object = new ExampleObject();
console.log("object.value");
console.log("-Before shadowing: " object.value);
object.value = "own";
console.log("-After shadowing: " object.value);
object.value = undefined;
console.log("-After assigning undefined: " object.value);
delete object.value;
console.log("-After deleting own property: " object.value);
Object.keys()
returns an array of own properties; for...in
loops over all (own and inherited) properties.
Returning to the original question: Since we want to assign all properties that both destination
and source
have, we need to consider the inherited properties as well. Object.keys()
won't allow us to do so, which is why I use my allKeys()
function and a for...in
loop.