Skip to content

Instantly share code, notes, and snippets.

@davidpaulhunt
Last active November 21, 2016 22:07
Show Gist options
  • Save davidpaulhunt/71c5e16d976dd865f21143dc5d7f9738 to your computer and use it in GitHub Desktop.
Save davidpaulhunt/71c5e16d976dd865f21143dc5d7f9738 to your computer and use it in GitHub Desktop.
Exploring Lodash #1

Introduction and _.isArray

If you're a JavaScript developer in 2016, you're likely at least aware of Lodash, a self-described

modern JavaScript utility library delivering modularity, performance, & extras.

Personally, it's a favorite of mine. From _.compact all the way to _.toPath, there's nothing like benefiting from the solution to a problem others have already solved; plus, I find its API to be enjoyable and intuitive.

Forgetting to be Thoughtful

As human beings, through some combination of habitual use, time constraints, and even laziness, it is possible to become overly reliant on the library. For example, take the function foo that accepts an array of keys and values to be set upon an object. Calling foo(['greeting', 'hello, world!']) should return the object { greeting: 'hello, world!' }.

function foo(keyValueArray) {
  const target = {};
  while (keyValueArray.length > 0) {
    const key = keyValueArray.shift();
    const value = keyValueArray.shift();
    target[key] = value;
  }
  return target;
}

While it's true, we could and may want to account for a number of edge cases, like converting foo's arguments to an Array, or flexibly accepting an object, and so on, let's say we're not going to do that. We demand only an Array be passed to foo, otherwise we're going to throw a custom error InvalidArgument "keyValueArray must be an Array".

If we've already required Lodash and want to maintain consistency, we can fall back to Lodash's _.isArray function.

function foo(keyValueArray) {
  if (!_.isArray(keyValueArray)) throw new InvalidArgument('keyValueArray must be an array');

  // while...
}

The Problem

However, is it worth requiring Lodash to check our argument's type if we have yet to do so? Technically, you could require only the function you need, ex: const isArray = require('lodash/fp/isArray'), but why? Honestly, in my opinion, the answer is consistency, at least that's the only real way I would convince myself to do so. Truthfully, using library utility methods like this is great until it's not. Something like _.isArray will probably never change its API. The same can't be said for all of Lodash's functions.

It can become a headache ensuring functions work as previously expected between versions and keeping very similar methods straight can become confusing, especially for less experienced programmers, for example: _.filter, _.findWhere, _.reject, _.find, and _.where were all a part of Lodash's API at or around the same time. Some did basically the same thing while others deviated slightly.

A Solution

To avoid this confusion, and limit your exposure to changes in external libraries, consistency in this context should mean consistently deferring to a language's built-in objects and functions.

So, with that said, how can we avoid requiring Lodash with the least amount of complexity? We use a built-in JavaScript method:

function foo(keyValueArray) {
  if (!Array.isArray(keyValueArray)) throw new InvalidArgument('keyValueArray must be an array');

  // while...
}

In fact, if we look under Lodash's hood, we see in the source that _.isArray is simply a reference to Array.isArray, even more encouragement to consistently defer to JavaScript's built-in objects and functions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment