Pure JavaScript Functions as a Replacement for Lodash

A brief overview of pure replacement functions over Lodash/Underscore.js

RC
Bits and Pieces

--

Functional Programming Illustrated

This post is a compilation of recipes of the most commonly used Lodash/Underscore.js utility functions to help you understand how much can be done using pure Javascript functions. Some of these functions are supported by ES5 and some require ES6 support.

The core design aspect of libraries like Lodash or Underscore.js is functional programming where you have pure functions that have no side-effects or do not mutate state. Well, the formal definition follows below…

What is functional programming anyway?

There are many ways to explain functional programming as a concept, but the definition below is succinct:

Functional programming is a style of programming which models computations as the evaluation of expressions. Contrast this with imperative programming where programs are composed of statements which change global state when executed. Functional programming typically avoids using mutable state and favors side-effect free functions and immutable data instead.

The key point to note is that the functions you write must not have any side-effects. That way it’s easier to test, maintain and most of all predictable.

Let us start with simple examples to illustrate the point and work our way to complex functions to see where the curve flips between native functions and library functions.

Tip: Install only the functions you need as Bit components

Using Bit you can strip any function, component or module from any of your libraries and make it individually reusable- with 0 refactoring. Try it out.

Example — lodash as a collection of reusable functions to use and share

1. find

The first function we will illustrate is the one that we use often. Let’s try to find the first element in a collection that satisfies a condition

_.find vs find

So, this is a very simple example and let’s investigate the performance of both these functions:

array find is way performant than _.find

You can inspect the benchmark code and play with variations using the playground below:

This is not to conclude that native functions are always performant over their Lodash counterparts. There are some functions that are complicated enough that it is possible that we write an implementation that is under-performant than what the library offers. But, when there is a choice of the native function being simple and more readable, you should definitely consider it as a better alternative.

2. filter

array.filter helps you extract all elements from a collection that satisfy a specific condition

_.filter vs array.filter
filter performance comparison

3. first and rest

There will many use-cases to get the first element in a collection and dump the rest to another.

first and rest using native spread operator

You would have probably used the spread operator ... in other contexts. Here, we are using it to de-structure array elements.

The performance benefits of first and rest are left as an exercise to the reader.

4. each

You are better off using a vanilla for loop than using any of the built-in iterators. This is one such use-cases where using lodash functions pay off.

_.each vs forEach vs map

The benchmark results look interesting:

_.each is the clear emergent winner!

Lodash’s each function is much faster because of the implementation decisions taken by the library that are browser specific.

The lo-dash developers explain that the relative speed of the native forEachvaries among browsers. Just because forEach is native does not mean that it is faster than a simple loop built with for or while. For one thing, the forEach has to deal with more special cases. Secondly, forEach uses callbacks, with the (potential) overhead of function invocation etc.

5. every

This function tests whether all elements in the array satisfied a specific condition. And the native version of it much faster!

_.every vs array.every

6. some

This function tests whether at least one of the elements in the array satisfied a specific condition

array.some vs _.some

7. includes

Check whether an element is contained or included in a collection.

check presence of an element in array
array.includes vs _.includes

8. uniq

Find unique elements in an array

We will be leverage the javascript’s Set data structure to convert an array to a set and convert it back to an array using the spread operator. Now, let’s see if it helping with performance to go through two conversions.

_.uniq is more performant

Now, there is a better way to filter the elements using the following snippet

elements.filter((v, i, a) => a.indexOf(v) === i)// definition: filter(callback(value, index, array)

Whether to use native functions or the lodash version is for you to decide…

9. compact

This is a useful function to remove falsey or undefined values from an array.

Now, we used a bit of syntactic sugar there to convert every element to boolean using array.filter(Boolean) to only return non-falsey values back.

So, having looked at multiple examples, the factors to take into consideration when choosing native functions over external libraries:

  • can you afford to include an external library in your application. With techniques like tree-shaking, you might be only including the modules that are used, but still would you want to use an external function?
  • in some cases, would you be willing to sacrifice code readability for performance or what is paramount to you?

Hope this post helps to serve as a starting point to take a decision in the right direction… thanks for reading :)!

--

--

Full Stack Engineer @ Pro.com , Ex-ThoughtWorker • Ruby,JavaScript, iOS, Frontend, Devops https://rcdexta.com