Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Immutable _.assign (assign with clone) from lodash underscore or other library?

Is there an alternative method available in lodash, underscore or other library that almost behaves the same way, except that it returns a new object instead of mutating the first argument?.

var o = { 'user': 'barney' }
var result = method(o, { 'age': 40 }, { 'user': 'fred' })

// o still { 'user': 'barney' }
// result is now { 'user': 'fred', 'age': 40 }
like image 217
Chad Avatar asked May 12 '15 15:05

Chad


People also ask

What does _ assign do?

The _. assign method will only assign the own enumerable properties from source objects, and will not do anything with inherited properties and methods from a prototype when dealing with objects that are created from a class.

Why is lodash underscore?

Because Lodash is updated more frequently than Underscore. js, a lodash underscore build is provided to ensure compatibility with the latest stable version of Underscore.

Is lodash merge immutable?

The functional programming variant of lodash assign does not mutate no arguments :) Use merge (the FP version of merge is also immutable) for recursively merging nested objects.


2 Answers

The most common way of doing this seems to use an empty object and assign onto that, like:

var result = _.assign({}, l, m, n, o, p);

This is not technically immutable but will produce a "new" object that did not exist before the function was called.

Bear in mind that even a very clever implementation of clone would have to do this same thing. It's trivial to create the new object manually, so most libraries don't worry about a helper for this case. The next closest thing would be _.create, which has more to do with assigning the correct prototype.

like image 174
ssube Avatar answered Oct 13 '22 13:10

ssube


I like defaults() for cases like this.

var user = { user: 'barney', age: 36 };

_.defaults({ age: 40 }, user);
// → { user: 'barney', age: 40 }

user;
// → { user: 'barney', age: 36 }

The first argument is the destination, and user isn't mutated. I like using defaults() when I need to override properties, as is the case here with age, but don't want to actually change anything in the original. Because defaults() will only add properties that resolve to undefined. The age property exists in the object literal, so it's value is kept.

The assign() approach works just as well - defaults() is just a different way to think about it.

like image 26
Adam Boduch Avatar answered Oct 13 '22 13:10

Adam Boduch