简体   繁体   中英

Is there a purely functional way to merge objects in JavaScript?

Say I have an object with some properties:

const obj = {
  key1: 1
  key2: 2
}

and I have a function someFunc that takes one object as a parameter. I want to pass obj with some additional parameters, like

someFunc({
  key1: 1
  key2: 2
  otherKey: 3
})

The problem is that I don't want to actually change the state of obj . After someFunc has been called it should not contain otherKey as a property.

This leaves Object.assign out of the question:

let ident = someObj => someObj;

ident(Object.assign(obj, {otherKey: 3}))
console.log(someObj); // -> {key1: 1, key2: 2, otherKey: 3}

Creating a new variable and assigning otherKey = 3 to it does the same thing.

I know I can use some sort of deep duplication - but that seems like an unnecessarily complex way of handling a fairly simple problem.

The most elegant way of doing this would be a pure function that takes some objects obj1, obj2 , returns the same output as Object.assign(obj1, obj2) , but alters neither of them. Is there some obvious way of doing this in JS that I haven't seen, or do I have to use some other library?

Just reverse the parameters to Object.assign - it will add the properties from obj to a new object:

ident(Object.assign({otherKey: 3}, obj))

Caution

But you must be careful about properties that are already present in obj as they will overwrite the ones in the new array.

You are dealing with immutability . Another way to accomplish thit is to use spread operator of ES6:

 const obj1 = { key1: 1, key2: 2, } const obj2 = { key1: 1, key2: 12, otherKey: 3 }; const merged = { ...obj1, ...obj2 }; console.log('merged: ', merged); console.log('obj1: ', obj1); console.log('obj2: ', obj2); 

You'll see that neither obj1 nor obj2 is altered

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM