A quick introduction to Lodash

November 1, 2016 by JavaScript   Angular  

borg


A few months ago I attempted to join the Borg collective, unfortunately things didn't quite work out as planned.

I initially experienced a bit of a culture shock (individuality, opinion is irrelevant, they only desire mindless drones - one mind, we are as one), their nanoprobes also proved to be incompatible with my physiology (not to mention the polymer nanocomposites used in their uniforms that gave me an unearthly rash), ultimately assimilation failed, so I was forced back into fluidic space.

"Forgive me: the Borg do not evolve, they conquer." - Lieutenant Commander Data

Back in fluidic space I was tasked to optimize the source code used in one of our bio-ships.

This specific class of Fluidian bio-ships currently makes use of AngularJS 1.5.x.

The previous guys (girls? not even sure if we have genders - at this point I am too afraid to ask), used some rather interesting "techniques", one of which included the use of jQuery, hmmm.

Now as a general rule of thumb, I avoid using jQuery in my Angular projects (read a little bit more about it over here).

More specifically they made use of the $.extend utility function, "equivalent" functionality in Angular can be found somewhere between the angular.extend and angular.merge functions (depending on your needs).

There is however one interesting caveat with regards to $.extend, have a look at the following objects in the snippet below.

var x = { a: 1, b: 2, c: 3, d: { e: 4, f: 5 }, o: { p: 6} };
var y = { b: null, d: undefined, o: { q: 7} };

Look what happens to x as soon as we run $.extend(x, y).

{ a: 1, b: null, c: 3, d: { e: 4, f: 5}, o: { q: 7} }

The first thing to notice is that undefined properties are not copied, secondly its a shallow copy that was performed from y to x. The latter can be remedied by passing true to the first argument of the function, e.g. $.extend(true, x, y), which performs a deep copy.

The exclusion of undefined properties on the other hand, is hardcoded into the behaviour of the function (something I grew accustomed to over the years -  proved to be quite useful whenever I created jQuery plugins.).

I contrast, when we run the angular.extend function on the same objects, we see the following changes to x.

{ a:1, b:null, c:3, d:undefined, o: { q: 7 } }

Admittedly at first glance I was mildly outraged, and after years of intense psychiatric treatment, followed by a pilgrimage (by foot, through space - starting in the Delta quadrant) to P'Jem (a Vulcan monastery on a planet near Andoria), I accepted that the angular.extend function behaviour is more logical that its jQuery counterpart.

I think (in my opinion, as ship counsellor) that the $.extend function is "doing too much", the angular.extend function in contrast merely copies everything from y to x (including undefined property values) and only performs a shallow copy (use a different function - angular.merge for a deep copy).

So be careful, don't go around replacing all your $.extend with angular.extend Winking smile

Excluding certain properties for certain scenario specific reasons, should really just be up to the developer.

But, lets think about this for a second, Angular and jQuery provides us with a very basic set of utility functions as it is, it is hardly part of their speciality, should we really be using the utility function provided by these libraries?

I always find myself needing more "power" (limited by the technology of my time), which boils down to writing custom utility functions.

Why not rather include a comprehensive specialist library into the equation? (especially if you're only including jQuery for its utility functions - like the guys back at space port) One you can reuse across your various applications, independent of any framework?

Up until recently I preferred using underscorejs as my utility library, but recently I migrated to its more evolved cousin, Lodash (currently maintained by the guys the brought you underscore as well).

Lodash is part of the JS Foundation, which features popular libraries like jQuery, dojo, grunt, moment, RequireJS etc.

If we were to write code that behaves like $.extend using Lodash, it would look something like this (guys familiar with underscore will immediately recognize this):

_.extendWith(x, y, function(target, source) {
	return _.isUndefined(source) ? target : source;
});

A lot more intuitive don't you think?

Now instead of needing to write custom utility functions every time you need them in a project, you will find that most of these would likely be covered already.

Need to do a quick bool check? Easy, _isBoolean, need to do a quick integer check, _isInteger, I am seeing too many codebases duplicating code, reinventing the wheel, why not include a tried and tested library instead?



Additional Reading

Lodash Homepage
Lodash Wikipedia Link


Leave a Comment


Only you November 8, 2016 by Jonathan McCarthy

I see what you did there lol!!