Looking over my content so far I am surprised that I have not yet wrote a post on _.assign in lodash, as well as the native alternative Object.assign methods. The _.assign method is one of many ways to go about combining a bunch of objects into a single object, and all around assign seems to work well for most situations, but there is a lot to be aware of when merging objects.
On the surface merging objects down together into one might seem to be a simple task, but often it is not so simple as one can run into all kinds of problems and concerns that have to do with things like copying be reference rather than value, and how to handle recursive references that might be present. So then the lodash assign method will work most of the time, but often there might be some other method that should be used such as merge, or one should at least clone objects that need to be cloned, or do more than just simply depend on one single method to get everything done all each time.
There is also the question of the prototype property of objects, and how that should be handled when combining two or more objects.
So in todays post I will be covering some use case scenarios of _.assign, and alternatives such as _.merge, and the native Object.assign method.
This is not a getting started post on lodash, or javaScrtipt in general and I expect that you have at least some background with these topics.
If I have an object before hand, and pass that as the first argument when calling lodash assign, and then any additional objects that I want to assign down on top of that object, the result will be that the object will be mutated in place. In other words if I create an object with say the object literal syntax, and then assign that object to a variable, and pass that variable to the lodash assign method as the first argument, I do not have to bother assigning the return value of lodash assign to another variable as the same object assigned to the variable will be mutated in place.
If you are still confused by what I am saying then just take a moment to study this source code example.
One way to avoid mutating an object in place would be to just simply pass a new object as the first argument.
The order in which objects are passed to the lodash assign method is of great importance. Objects that are passed as later arguments will override any objects passed as an argument with a lower argument index when more than one object has the same key name.
For another example of the assign method I will start out with a bunch of objects that contain properties, and methods that I will like to combine together into a single method. In this example I will not be doing anything advanced involving nested objects or the prototype chain, and I will be giving both lodash, and native Object.assign examples.
So say I have an object that contains an x, and y position, as well as another object that contains deltas for x and y. In addition I also have an object of methods that I would like to use with these values. I could use Function.call, but before I do that I would still need to combine the position and delta values into a single object. There are a few options for doing so and _.assign is one of them.
All I have to do is pass an object that is the object that I want everything assigned to as the first argument. For this example I just give it an empty object because I do not want to mangle any of the other objects. After that I just start passing objects that I want assigned to the empty object.
This results as in an object that works as expected. However There is much that I am not covering in this example such as what happens when there are name space collisions, what happens to the prototype, and what if a nested object is used and it’s values change. More on all that later but for now you should get the basic idea of what _.assign is good for.
So when dealing with nested objects you might run into problems, depending on how you expect objects to combine together. As the name suggested _.assign, well, assigns what is in the objects that you give it to the target object that is given as the first argument. In other worlds objects are copied in by reference and not by value which is the typical case with objects. In many cases this does not present a problem because it may be what is expected or desired.
However if the typical copy by reference behavior is not what is expected, then when one of the values of the objects that are given to assign changes, then it will also change in the target object where everything is assigned to. If this is not what is desired then there are a number of ways to change that such as using a method like _.cloneDeep when passing in the objects, or better yet using another lodash method know as _.merge.
As you can see when using _.merge changing the values of the original objects has no effect on the object that had values added in compared to _.assign.
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.
There is a number of ways of resolving this one way would be to use _.create to set the prototype back to the object. However there is also the _.extend method which is an alias for _.assignIn that can be used as a way to keep method from a prototype.These different solutions work in very different ways so in this section I will cover what some of the options are.
So one way to bring the prototype back after using _.assign would be to just use _.create to create a new object with the desired prototype, and pass in the result of an _.assign as the properties to use with that object.
This keeps the prototype in the prototype where it should be rather than another solution in which the prototype ends up getting mixed in with regular old object properties. There is also of course the native Object.create which also works the same way.
Another option would be to use _.extend which is an alias for _.assignIn. The _.assignIn method works like _assign, but it will bring in the prototype method as well.
This can defeat the purpose of the prototype object if dealing with a large collection of objects that share the same prototype, so this solution should be avoided. Unless for some reason you want ot need to do it of course.
Assuming that it is always there to work with it would seem that Object.assign works in more or less the same way. So then _.assign is another one of those methods in lodash that pull it’s relevance into question as time goes on. Keep in mode that this is not the case with all lodash methods, some do bring a bit something more, but it would appear that _.assign is not a good example of that, aside from the safety net deal if that is important to you.