DEV Community

Why is Lodash Still Useful?

John Au-Yeung on March 26, 2020

Subscribe to my email list now at http://jauyeung.net/subscribe/ Follow me on Twitter at https://twitter.com/AuMayeung Many more articles at http...
Collapse
 
lexlohr profile image
Alex Lohr • Edited

To do the same with ES methods, just the first two examples:

_.times

// import * as _ from "lodash";
const getRandomInteger = () => Math.round(Math.random() * 100);  
// let result = _.times(5, getRandomInteger);  
const result = Array(5).fill().map(getRandomInteger);  
console.log(result);

_.debounce

//import * as _ from "lodash";
let checkPositiveNumberTimeout;
const checkPositiveNumber = e => {
  clearTimeout(checkPositiveNumberTimeout);
  checkPositiveNumberTimeout = setTimeout(() => console.log(+e.target.value > 0), 600);
};

const numInput = document.querySelector("input[type=number]");  
// numInput.addEventListener("input", _.debounce(checkPositiveNumber, 600));
numInput.addEventListener("input", checkPositiveNumber);

These two example illustrate well that some things are easier to achieve without lodash than others. For me, the rule of thumb is: if I use a lodash method, I use it separately (never import all of it, and if possible, use the es version that can be tree-shaked!) and make sure I reuse it throughout the code so I actually get something in return.

In a surprisingly lot of cases I have seen, the use of utilities like lodash means outsourcing the deeper understanding of a problem to a library. While that can help speed up development in the short term, it might become a convenient habit, so much that one is tempted to overcomplicate the issue at hand in order to use these utilities when it could have been far simpler solved with native methods.

That does not mean you should not use lodash, but you should be conscientious about the implications.

Collapse
 
patarapolw profile image
Pacharapol Withayasakpunt • Edited

but you should be conscientious about the implications.

This.

It makes me unsure if I should use lodash.clonedeep or lodash.merge... If I write it myself, I can be sure of the implications.

Also, lodash is too magical and too widely accepting in some methods, such as lodash.filter. (I saw a lot in lowdb.)

Collapse
 
lexlohr profile image
Alex Lohr

A very nice example is _.isEmpty(): in most cases, you are testing if an object has no enumerable keys. You'll rarely need to check at the same time if the length of an array or a string is zero, but lodash will (needlessly in the stated case) check the input for all available types.

Thread Thread
 
aumayeung profile image
John Au-Yeung

This is one of the ones that we can implement ourselves without much effort.

Collapse
 
aumayeung profile image
John Au-Yeung

I think the array's built-in filter method is pretty good so I never want to use the Lodash version.

Collapse
 
ionline247 profile image
Matthew Bramer

The problem with all the examples is

import * as _ from "lodash";

That'll pull in the entire lib. At this point, if you're looking for a utility, it should be very selective, much like your article suggests. That means your npm install should only pull in that utility, not the whole library.

Collapse
 
aumayeung profile image
John Au-Yeung

You're right. Just import the methods you need to use. That's more efficient.

Collapse
 
mateiadrielrafael profile image
Matei Adriel

Someone in another component has already shown how to implement times and debounce.Get can be achived with optional chaining, so heres how to do keyBy:

const keyBy = (arr, key) => Obhect.fromEntries(arr.map(o => [o[key], o]))

...and with types:

const keyBy = <T extends object, K extends keyof T>(arr: T[], key: K): Record<T[K] extends (string | number) ? T[K] : never, T>

(Have't tested this since I'm on mobile rigut now, but you yet the idea)

Conclusion

There’s no way to do this easily with plain JavaScript without writing multiple lines of code

Since its doable in 1 line your statemet kinda false

Collapse
 
patarapolw profile image
Pacharapol Withayasakpunt

To avoid Object.fromEntries, there is .reduce.

arr.map(o => [o[key], o]).reduce((prev, [k, v]) => { ...prev, [k]: v }, {})

Actually, with map, filter, reduce -- you can do a lot.

It is impossible to say that you cannot do something in one-liner JavaScript, because minified JS is also a one liner.

Collapse
 
aumayeung profile image
John Au-Yeung

I agree. I think there're things like differenceWith in Lodash that are harder to implement by ourselves and not available in the standard library.

Collapse
 
ajkachnic profile image
Andrew

Can’t you now using optional chaining instead of _get()

let obj = {
  person: {
    name: "Something"
  }
}
const name = obj?.person?.name
Collapse
 
aumayeung profile image
John Au-Yeung

I'm not sure if it's finalized yet, but hopefully, it will be soon so that we don't need Lodash for it.

Collapse
 
jlave_dev profile image
James Lave

Thanks for the post, John! I'll admit, Lodash always felt "dirty" to me, especially since so many of its methods are now part of the ECMA standard or can be implemented in a few lines of native JavaScript. But the ones you highlighted are still very useful.

Collapse
 
aumayeung profile image
John Au-Yeung

It's useful if you don't want to create your own function to do the things it does.

Collapse
 
jharteaga profile image
Jose Arteaga

Very helpful! Thanks for sharing this worthy information.

Collapse
 
aumayeung profile image
John Au-Yeung

Thanks for reading