Useful Lodash utilities
In this post, you can find a collection of the most useful lodash utilities. Each method has a quick description, its signature, and examples on how to use it. It also has links to the documentation, the weekly downloads (from NPM), and the bundle size from bundlephobia.
The goal here is to list as many methods as possible, in the least possible space. I tried not to include methods that are identical to their native counterparts unless they are popular. You can’t say that this post is something new or groundbreaking, but you can rather see it as a resource that will remind/introduce you to cool lodash methods quickly. To give you an idea, most of the examples are from the lodash documentation. The descriptions, on the other hand, are custom because I wanted to provide clear, non-technical explanations (at least I tried). Finally, I assume that you download the individual packages, not the whole library. As a result, you won’t see me calling the methods with the underscore e.g. _.map()
but directly e.g. map()
.
* You’ll see that many functions have a parameter named iteratee with a default value of identity. Both of them are helper lodash functions listed under the Utils section. Click the links above to learn more.
Table of contents
- Array: chunk(), flatten(), compact(), set methods, zip().
- Collection: countBy(), groupBy(), orderBy(), partition(), popular with ES6 alternatives, other collection methods.
- Math: maxBy(), minBy(), round().
- String: truncate(), pad(), deburr(), escape() - unescape(), capitalize(), change letter casing, other sting methods.
- Util: identity() - iteratee(), bindAll(), flow(), times(), range(), other util methods.
- Lang: clone(), cloneDeep(), isEqual(), isEmpty(), type checking, other type-checking methods, type conversion methods.
- Seq
- Object: get() - set(), has() - hasIn(), assign() - assignIn(), merge(), defaults() - defaultsDeep(), pick() - omit(), toPairs() - fromPairs(), keys() - values(), other object methods.
- Function: debounce() - throttle(), once(), curry() - partial(), bind(), other function methods.
- Links
Array
Methods to chunk, flatten, and perform set operations on arrays.
chunk
chunk(array, chunkSize = 1)
: Split an array into equal chunks. Docs - weekly downloads - size.
chunk(["a", "b", "c", "d"], 2); // [["a", "b"], ["c", "d"]]
chunk(["a", "b", "c", "d"], 3); // [["a", "b", "c"], ["d"]]
flatten - flattenDeep - flattenDepth
flatten(array)
: Flatten a nested array by 1 level. Docs - weekly downloads - size.flattenDeep(array)
: Flatten the array recursively. Docs - weekly downloads - size.flattenDepth(array, depth = 1)
: Specify the levels. Docs - weekly downloads - size.
const nested = [1, [2, [3, [4]], 5]];
flatten(nested); // [1, 2, [3, [4]], 5]
flattenDeep(nested); // [1, 2, 3, 4, 5]
flattenDepth(nested, 1); // [1, 2, [3, [4]], 5]
flattenDepth(nested, 2); // [1, 2, 3, [4], 5]
compact
compact(array)
: Remove the falsey values. Docs - weekly downloads - size.
compact([0, 1, false, 2, "", 3]); // [1, 2, 3]
Sets
I think it’s easier to understand what each method does in this section by looking at the pictures, rather than reading the descriptions. Set images are from Wikipedia.
union
union(arrays)
: Create an array that holds all the unique values from both arrays. Docs - weekly downloads - size.unionBy(arrays, iteratee = identity)
: It’s likeunion
, but you can specify the unique criterion. Docs - weekly downloads - size.
union([2, 1], [2, 3]); // [2, 1, 3]
unionBy([{ x: 1 }], [{ x: 2 }, { x: 1 }], "x"); // [{ x: 1 }, { x: 2 }]
intersection
intersection(arrays)
: Create an array that holds only the unique values that exist in both arrays. Docs - weekly downloads - size.intersectionBy(arrays, iteratee = identity)
: It’s likeintersection
, but you can specify the unique criterion. Docs - weekly downloads - size.
intersection([2, 1], [2, 3]); // [2]
intersectionBy([{ x: 1 }], [{ x: 2 }, { x: 1 }], "x"); // [{ x: 1 }]
difference
difference(arrays)
: Create an array that holds the unique values that exist in the first array but not in the second. Docs - weekly downloads - size.differenceBy(arrays, iteratee = identity)
: It’s likedifference
, but you can specify the unique criterion. Docs - weekly downloads - size.
difference([2, 1], [2, 3]); // [1]
differenceBy([{ x: 2 }, { x: 1 }], [{ x: 1 }], "x"); // [{ x: 2 }]
See also without if you prefer to pass values instead of a second array.
xor
xor(arrays)
: Create an array that holds the unique values from both arrays but not those that exist in both. Docs - weekly downloads - size.xorBy(arrays, iteratee = identity)
: It’s likexor
, but you can specify the unique criterion. Docs - weekly downloads - size.
xor([2, 1], [2, 3]); // [1, 3]
xorBy([{ x: 1 }], [{ x: 2 }, { x: 1 }], "x"); // [{ x: 2 }]
zip
zip(arrays)
: Group arrays, see the example. Docs - weekly downloads - size.
zip(["a", "b"], [1, 2], [true, false]); // [["a", 1, true], ["b", 2, false]]
// edge cases:
zip(["a", "b"], [1, 2, 3]); // [["a", 1], ["b", 2], [undefined, 3]], different length.
zip(["a", "b"]); // [["a"], ["b"]], single array.
Collection
You can use these methods for array-like objects and regular objects.
Example users array
I will reference this array in some examples.
const users = [
{ name: "barney", age: 36, active: false },
{ name: "fred", age: 40, active: true },
{ name: "pebbles", age: 1, active: false },
];
countBy
countBy(collection, iteratee = identity)
: Count the different values. Docs - weekly downloads - size.
countBy([1, 1, 2]); // { "1": 2, "2": 1 }
countBy([6.1, 4.2, 6.3], Math.floor); // { "4": 1, "6": 2 }
countBy(["one", "two", "three"], "length"); // { "3": 2, "5": 1 }
// 2 items with length 3, 1 item with length 5.
countBy(users, "active"); // { false: 2, true: 1 }, by an object property.
groupBy
groupBy(collection, iteratee = identity)
: Group the different values. Example users array - Docs - weekly downloads - size.
groupBy([6.1, 4.2, 6.3], Math.floor); // { "4": [4.2], "6": [6.1, 6.3] }
groupBy(["one", "two", "three"], "length"); // { "3": ["one", "two"], "5": ["three"] }
groupBy(users, "active"); // { "false": [barney, pebbles], "true": [fred] }
orderBy
orderBy(collection, iteratees = identity, [order])
: Sort the collection by a property. It’s like sortBy, but you can also set the order (asc/desc). Example users array - Docs - weekly downloads - size.
orderBy(users, "age", "desc"); // [fred (40), barney (36)], pebbles (1)]
orderBy(users, ["name", "age"], ["asc", "desc"]); // by name and then (if equal) by age.
// [barney("b",36), fred("f",40), pebbles("p",1)]
partition
partition(collection, predicate = identity)
: Split the collection into two groups. Example users array - Docs - weekly downloads - size.
partition(users, (o) => o.active); // [[fred(true)], [barney(false), pebbles(false)]], func.
partition(users, { age: 1, active: false }); // [[pebbles], [barney, fred]], object.
partition(users, ["active", false]); // [[barney, pebbles], [fred]], array.
partition(users, "active"); // [[fred], [barney, pebbles]], string.
Popular methods with ES6 alternatives
These methods are useful if you want to support Internet Explorer—instead of relying on polyfills and native methods—or if you want to use the iteratee shorthand. It has been also reported in the past that they are more performant than the native methods, but I can’t find a definitive resource for that.
includes(collection, value, fromIndex = 0)
Docs - weekly downloads - sizeeach/foreach(collection, iteratee = identity)
Docs - weekly downloads - sizemap(collection, iteratee = identity)
Docs - weekly downloads - sizefilter(collection, predicate= identity)
Docs - weekly downloads - sizefind(collection, predicate = identity, fromIndex = 0)
Docs - weekly downloads - sizereduce(collection, iteratee = identity, accumulator)
Docs - weekly downloads - size
/* 1 */ includes([1, 2, 3], 1); // true
/* 2 */ forEach([1, 2], (value) => console.log(value)); // Logs 1 then 2.
/* 3 */ map([4, 8], (n) => n * 2); // [8, 16]
/* 3 */ map(users, "name"); // ["barney", "fred", "pebbles"]
/* 4 */ filter(users, { age: 36, active: false }); // [barney]
/* 4 */ filter(users, ["active", false]); // [barney, pebbles]
/* 5 */ find(users, ["active", false]); // [barney], the first it finds.
/* 6 */ reduce([1, 2, 3], (acc, next) => (acc += next), 0); // 6
Other collection methods
shuffle(collection)
Shuffle the elements. Docs - weekly downloads - sizesample(collection)
Get a random element. Docs - weekly downloads - size
shuffle([1, 2, 3, 4]); // [4, 1, 3, 2]
sample([1, 2, 3, 4]); // 2, get a random element.
Math
These are three of the most interesting lodash math methods.
maxBy
maxBy(array, iteratee = identity)
: Find the max in an array. Example users array - Docs - weekly downloads - size.
maxBy(users, (o) => o.age); // fred object, function
maxBy(users, "age"); // fred object, shorthand
minBy
minBy(array, iteratee = identity)
: Find the min in an array. Example users array - Docs - weekly downloads - size.
minBy(users, (o) => o.age); // pebbles object, function
minBy(users, "age"); // pebbles object, shorthand
round
round(number, precision = 0)
: It’s like Math.round but with precision. Docs - weekly downloads - size.
round(4.006); // 4
round(4.006, 2); // 4.01
round(4.004, 2); // 4
round(4060, -2); // 4100, 60 > 50 (middle with 2 precision)
round(4060, -3); // 4000, 60 < 500 (middle with 3 precision)
String
Methods to truncate, pad, escape characters, and change the casing of a string.
truncate
Shorten a string to a certain length: Docs - weekly downloads - size.
truncate(string, { length = 30, omission = "...", [separator] });
const body = "hi-diddly-ho there, neighborino";
truncate(body); // "hi-diddly-ho there, neighbo..."
truncate(body, { length: 24, separator: " " }); // "hi-diddly-ho there,..."
truncate(body, { length: 24, separator: /,? +/ }); // "hi-diddly-ho there..."
truncate(body, { omission: " [...]" }); // "hi-diddly-ho there, neig [...]"
pad
pad(string, length = 0, padCharacters)
: Adds a character before and after the string. See also padStart and padEnd. Docs - weekly downloads - size.
pad("hello", 10); // " hello ", 2 spaces at the start, 3 at the end.
pad("mark", 10, "_"); // "___mark___"
padStart(342, 10, "."); // ".......342", useful in CLI tools.
padStart(12, 10, "."); // "........12"
deburr
deburr(string)
: Removes combining diacritical marks, and converts Latin-1 Supplement and Latin Extended-A letters to basic Latin letters. Docs - weekly downloads - size.
deburr("déjà vu"); // "deja vu"
escape - unescape
escape(string)
: Convert& < > '' '
to& < > " '
. In other words, convert characters to HTML entities. Docs - weekly downloads - size.unescape(string)
: The opposite of escape, convert HTML entities to characters. Docs - weekly downloads - size.
escape("fred, barney, & pebbles"); // "fred, barney, & pebbles"
unescape("fred, barney, & pebbles"); // "fred, barney, & pebbles"
See also escapeRegExp.
capitalize
capitalize(string)
: Capitalize a string. Docs - weekly downloads - size.
capitalize("mark"); // Mark
capitalize("MARK"); // Mark
capitalize("mArK"); // Mark
Change letter casing
cameCase(string)
: Docs - weekly downloads - size.kebabCase(string)
: Docs - weekly downloads - size.snakeCase(string)
: Docs - weekly downloads - size.startCase(string)
: Docs - weekly downloads - size.
camelCase("--foo-bar--"); // "fooBar"
camelCase("__FOO_BAR__"); // "fooBar"
camelCase("Foo Bar");
kebabCase("Foo Bar");
snakeCase("Foo Bar");
startCase("Foo Bar");
Other popular string methods
template
: It’s popular but not really relevant now that we have template literals. Docs - weekly downloads - size.
Util
General functional programming utilities.
identity and iteratee
identity(value)
: A helper utility that returns the first value it receives. It’s used as a default value for theiteratee
in many methods. It’s like the constant method. Docs - weekly downloads - sizeiteratee(func = identity)
: Creates a new function. If thefunc
argument is a function, the new function callsfunc
with the arguments it receives—doesn’t sound really useful. Whenfunc
is a property name (e.g.user.age
), though, the new function returns the value for that property. Finally, iffunc
is an array or object, it returns true for elements that have those properties, or false otherwise. Consider the examples below. Docs - weekly downloads - size
const users = [
{ name: "barney", age: 36, active: true },
{ name: "fred", age: 40, active: false },
];
identity(users[0]) === users[0]; // true
filter(users, iteratee({ name: "barney" })); // [barney], `matches` shorthand.
filter(users, iteratee(["name", "fred"])); // [fred], `matchesProperty` shorthand.
map(users, iteratee("name")); // ["barney", "fred"], `property` shorthand.
See also matches, matchesProperty, property, and method.
bindAll
bindAll(object, methodNames)
: For the object methods you choose, this
inside them points to the object, no matter how they’re called. Docs - weekly downloads - size
const view = {
label: "docs",
click: function () {
console.log("clicked " + this.label);
},
};
bindAll(view, ["click"]);
element.addEventListener("click", view.click); // "clicked docs"
flow
flow(funcs)
: Chain functions from left to right. See also flowRight. Docs - weekly downloads - size
const add = (a, b) => a + b;
const square = (n) => n * n;
const addSquare = flow([add, square]); // or flow(add, square) if you prefer.
addSquare(1, 2); // returns 9. Returns 3 after `add` and 9 after `square`
Lodash FP and currying can make flow even more interesting.
times
times(n, iteratee = identity)
: Call the iteratee
n
times—passing the current index each time—and return an array with the results. Docs - weekly downloads - size
times(3); // [0, 1, 2]
times(3, String); // ["0", "1", "2"]
times(4, constant(0)); // [0, 0, 0, 0]
range - rangeRight
Create an array where you specify the start, end, and the step. The start number is optional.
range(start = 0, end, step = 1)
: Docs - weekly downloads - sizerangeRight(start = 0, end, step = 1)
: Docs - weekly downloads - size
range(4); // [0, 1, 2, 3]
range(-4); // [0, -1, -2, -3]
range(0, 20, 5); // [0, 5, 10, 15]
range(1, 4, 0); // [1, 1, 1]
range(0); // []
rangeRight(4); // [3, 2, 1, 0]
rangeRight(-4); // [-3, -2, -1, 0]
Other interesting methods
cond(pairs)
Ιt’s like aswitch
statement, but you create it on the fly by composing functions. See also toPairs. Docs - weekly downloads - sizeconforms(source)
Similar to the object shorthand of the iteratee but you can specify the operation. Docs - weekly downloads - sizenoop()
A method that returnsundefined
. Useful when you want to call a method no matter what, without getting an error. See the example. Docs - weekly downloads - sizeuniqueId(prefix = '')
Generate a unique ID with an optional prefix. Docs - weekly downloads - sizeover(iteratees = identity)
Docs - weekly downloads - size
const func = cond([
[matches({ a: 1 }), /* . */ constant("matches A")],
[conforms({ b: isNumber }), constant("matches B")],
[stubTrue, /* .......... */ constant("no match")],
]);
/* 1 */ func({ a: 1, b: 2 }); // "matches A"
/* 1 */ func({ a: 0, b: 1 }); // "matches B"
/* 1 */ func({ a: "1", b: "2" }); // "no match"
/* 2 */ filter(
users,
conforms({ age: (n) => n > 1, active: (n) => n === true })
); // [fred]
/* 3 */ times(2, noop); // [undefined, undefined]
/* 3 */ const callbackThatMustBeCalled = userCallback || noop;
/* 4 */ uniqueId(); // "105"
/* 4 */ uniqueId("contact_"); // "contact_104"
/* 5 */ const func = over([Math.max, Math.min]);
/* 5 */ func(1, 2, 3, 4); // [4, 1]
Lang
Utilities that simplify cloning objects, type checking, and type conversions.
clone
clone(value)
: Create a shallow copy of a value. Docs - weekly downloads - size
const objects = [{ a: 1 }, { b: 2 }];
const shallow = clone(objects);
shallow[0] === objects[0]; // true
cloneDeep
cloneDeep(value)
: Create a deep copy of a value. Docs - weekly downloads - size
const objects = [{ a: 1 }, { b: 2 }];
const deep = cloneDeep(objects);
deep[0] === objects[0]; // false
isEqual
isEqual(value, other)
: Deep comparison between two values. Docs - weekly downloads - size
const object = { a: 1 };
const other = { a: 1 };
isEqual(object, other); // true
object === other; // false
isEmpty
isEmpty(value)
: Check if a value is empty. For array-like: length is 0; for objects: no own properties; for maps/sets: size is 0. Docs - weekly downloads - size
isEmpty(null); // true
isEmpty(true); // true
isEmpty(1); // true
isEmpty([1, 2, 3]); // false
isEmpty({ a: 1 }); // false
Type-checking
isNumber
isNumber(value)
: Check if the value is a Number
primitive or object. Docs - weekly downloads - size
isNumber(3); // true
isNumber(Number.MIN_VALUE); // true
isNumber(Infinity); // true
isNumber("3"); // false
isInteger
isInteger(value)
: Docs - weekly downloads - size
isInteger(3); // true
isInteger(Number.MIN_VALUE); // false
isInteger(Infinity); // false
isInteger("3"); // false
isInteger(3.2); // false
isPlainObject
isPlainObject(value)
: Checks if value is a plain object, that is, an object created by the Object
constructor or one with a [[Prototype]]
of null
. Docs - weekly downloads - size
function Foo() {
this.a = 1;
}
isPlainObject(new Foo()); // false
isPlainObject([1, 2, 3]); // false
isPlainObject({ x: 0, y: 0 }); // true
isPlainObject(Object.create(null)); // true
isMatch
isMatch(object, source)
: See if the object has a property with that value. If you partially apply the source, it’s the same as matches. Docs - weekly downloads - size
const object = { a: 1, b: 2 };
isMatch(object, { b: 2 }); // true
isMatch(object, { b: 1 }); // false
Other interesting type-checking methods
isArray, isArrayLike, isBoolean, isDate, isElement, isError, isFinite, isFunction, isNative, isObject, isObjectLike, isRegExp, isSafeInteger, isString, isTypedArray, and isUndefined.
Type conversion methods
toArray, toFinite, toInteger, toLength, toNumber, toPlainObject, toSafeInteger, and toString.
Seq
Chain lodash methods with the Sequence methods. An alternative is the flow method.
const youngest = _.chain(users) // start the chain by passing a value.
.sortBy("age")
.map((o) => `${o.name} is ${o.age}`)
.head() // get the first element from the array.
.value(); // "pebbles is 1", get the value.
See also tap, thru. They both intercept the chain and can modify the value, but thru
returns the value.
Object
Methods that simplify object creation, validation, getting/setting properties, and more.
get - set
get(object, property, [defaultValue])
: Get the object property, without throwing reference errors if it doesn’t exist. Docs - weekly downloads - sizeset(object, property, value)
: Set an object property. Docs - weekly downloads - size
const object = { a: [{ b: { c: 3 } }] };
get(object, "a[0].b.c"); // 3
get(object, ["a", "0", "b", "c"]); // 3
get(object, "a.b.c", "default"); // 'default'
set(object, "a[0].b.c", 4); // { a: [{ b: { c: 4 } }] }
set(object, ["x", "0", "y", "z"], 5); // { a: [{ b: { c: 4 } }], x: [{ y: { z: 5 } }] }
See also unset
has - hasIn
has(object, property)
: Check if the object directly has the property, excluding inherited methods. Docs - weekly downloads - sizehasIn(object, property)
: Check if the object has the property, directly or by inheritance. Docs - weekly downloads - size
const object = { a: { b: 2 } };
const other = Object.create({ a: Object.create({ b: 2 }) }); // inheritance
has(object, "a"); // true
has(object, "a.b"); // true
has(object, ["a", "b"]); // true
has(other, "a"); // false, a is not a direct property of other.
hasIn(other, "a"); // true
assign - assignIn
assign(object, otherObjects)
: Assign the own properties of theotherObjects
to theobject
. Docs - weekly downloads - sizeassignIn(object, otherObjects)
: Assign the own and inherited properties of theotherObjects
to theobject
. Docs - weekly downloads - size
function Foo() {
this.a = 1;
}
function Bar() {
this.c = 3;
}
Foo.prototype.b = 2;
Bar.prototype.d = 4;
assign({ a: 0 }, new Foo(), new Bar()); // { a: 1, c: 3 }
assignIn({ a: 0 }, new Foo(), new Bar()); // { a: 1, b: 2, c: 3, d: 4 }
merge
merge(object, otherObjects)
: It’s likeassignIn
but can merge nested object properties too. See also mergeWith. Docs - weekly downloads - size
const object = { a: [{ b: 2 }, { d: 4 }] };
const otherr = { a: [{ c: 3 }, { e: 5 }] };
merge(object, otherr); // { a: [{ b: 2, c: 3 }, { d: 4, e: 5 }] }
assignIn(object, otherr); // { a: [{ c: 3 }, { e: 5 }] }
assign(object, otherr); // { a: [{ c: 3 }, { e: 5 }] }
defaults - defaultsDeep
defaults(object, defaultProperties)
: If the object doesn’t already have the default properties, add them. Docs - weekly downloads - sizedefaultsDeep(object, defaultProperties)
: Same asdefaults
but recursively for nested properties too. Docs - weekly downloads - size
defaults({ a: 1 }, { b: 2 }, { a: 3 }); // { a: 1, b: 2 }
defaultsDeep({ a: { b: 2 } }, { a: { b: 1, c: 3 } }); // { a: { b: 2, c: 3 } }
pick - omit
pick(object, properties)
: Create an object and choose the properties you want. Docs - weekly downloads - sizeomit(object, properties)
: Create an object and choose what properties you don’t want. (It’s slower thanpick
) Docs - weekly downloads - size
const object = { a: 1, b: "2", c: 3 };
pick(object, ["a", "c"]); // { a: 1, c: 3 }
omit(object, ["a", "c"]); // { b: "2" }
toPairs - fromPairs
toPairs(object)
: Put the object’s own key-value pairs in an array. Each entry (pair) is also an array. Docs - weekly downloads - size.fromPairs(pairs)
: The opposite fromtoPairs
(this is an Array method by the way). Docs - weekly downloads - size.
toPairs({ a: 1, b: 2 }); // [["a", 1], ["b", 2]]
fromPairs([
["a", 1],
["b", 2],
]); // { a: 1, b: 2 }
keys - values
keys(object)
: Create an array with the object’s own keys. For inherited properties see keysIn. Docs - weekly downloads - sizevalues(object)
: Create an array with the object’s own values. For inherited values see valuesIn. Docs - weekly downloads - size
function Foo() {
this.a = 1;
this.b = 2;
}
Foo.prototype.c = 3;
keys(new Foo()); // ["a", "b"]
keys("hi"); // ["0", "1"]
keysIn(new Foo()); // ["a", "b", "c"]
values(new Foo()); // [1, 2]
values("hi"); // ["h", "i"]
valuesIn(new Foo()); // [1, 2, 3]
Other object methods
create(prototype, optionalProperties)
Create an object that inherits from (is linked to) the prototype object (first parameter). Docs - weekly downloads - sizeinvert(object)
Invert the object’s key-value pairs. Docs - weekly downloads - sizeinvoke(object, property, [args])
Invoke an object’s method. You can also pass arguments. Docs - weekly downloads - sizemapValues(object, iteratee = identity)
Docs - weekly downloads - sizetransform
Similar toreduce
but you can stop the iteration by returningfalse
. Docs - weekly downloads - size
/* 2 */ const object = { a: 1, b: 2, c: 1 };
/* 2 */ invert(object); // { 1: "c", 2: "b" }
/* 3 */ const object = { a: [{ b: { c: [1, 2, 3, 4] } }] };
/* 3 */ invoke(object, "a[0].b.c.slice", 1, 3); // [2, 3]
/* 4 */ mapValues(users, "age"); // { '0': 36, '1': 40, '2': 1 }
/* 5 */ transform(
[2, 3, 4],
function (result, n) {
result.push((n *= n));
return n % 2 == 0;
},
[]
); // [4, 9]
Function
Methods that moderate the execution of functions and some that help with functional programming like currying/partial application.
debounce - throttle
debounce(func, wait = 0, options={ leading = false, trailing = true })
: Groups thefunc
calls if they happen in less thanwait
ms (imagine the calls as a sudden burst of events). By “group” I mean it doesn’t allow thefunc
to execute. Docs - weekly downloads - sizethrottle(func, wait = 0, options={ leading = true, trailing = true })
: Calls thefunc
at most everywait
ms. Unlikedebounce
,throttle
guarantees the execution of thefunc
at least everywait
ms. Docs - weekly downloads - size
True for both of them: If leading and trailing options are true
, func
is called on the trailing edge of the timeout only if the function is called more than once during the wait
timeout.
function scrollHandler(e) {
console.log("Scrolling and rolling");
}
const debounced = _.debounce(scrollHandler, 600);
const throttled = _.throttle(scrollHandler, 600);
document.addEventListener("scroll", scrollHandler); // regular
// document.addEventListener("scroll", debounced); // debounce
// document.addEventListener("scroll", throttled); // throttle
once
once(func)
: Create a function that can be called only once. Docs - weekly downloads - size
const initialize = once(createApplication);
initialize(); // `createApplication` is invoked
initialize(); // // `createApplication` is not invoked
curry - partial
A blog post that explains the differences between them: Currying versus partial application (with JavaScript code)
curry(func, arity = func.length)
: Docs - weekly downloads - sizepartial(func, parameters)
: Docs - weekly downloads - size
const regularFunction = (a, b, c) => [a, b, c];
const curried = curry(regularFunction);
curried(1)(2)(3);
curried(1, 2)(3); // [1, 2, 3]
curried(1, 2, 3); // [1, 2, 3]
const partiallyApplied = partial(regularFunction, 1, 2);
partiallyApplied(3);
bind
bind(func, this, optionalArgs)
: Create a function with your preferred this
binding, and optionally pass (or apply) arguments to that function. The difference with Function.prototype.bind
is that it doesn’t set the length
property. Docs - weekly downloads - size
function greet(greeting, punctuation) {
return greeting + " " + this.name + punctuation;
}
const user = { name: "fred" };
const bound = bind(greet, user, "hi");
bound("!"); // "hi fred!"
Other function methods
memoize(func, [resolver])
Cache the result of a function. Docs - weekly downloads - sizeunary(func)
Creates a function that accepts only one argument. Docs - weekly downloads - sizewrap(value, wrapper = identity)
Wrap a function within another function (kind of). Docs - weekly downloads - sizeafter(n, func)
Creates a function that invokesfunc
only after the function has been calledn
times. Docs - weekly downloads - sizebefore(n, func)
Creates a function that can be called at mostn - 1
times. Docs - weekly downloads - size
/* 2 */ map(["6", "8", "10"], unary(parseInt)); // [6, 8, 10], what you'd expect
/* 2 */ ["6", "8", "10"].map(parseInt); // [6, NaN, 2], wrong because parseInt(string, radix)
/* 3 */ const p = _.wrap(
_.escape,
(func, text) => `<p> + ${func(text)} + </p>`
);
/* 3 */ p("fred, barney, & pebbles"); // "<p>fred, barney, & pebbles</p>"
/* 4 and 5*/
const saves = ["profile", "settings", "messages"];
const logTheFirst2 = _.before(saves.length, function () {
console.log("Logging the save.");
});
const completionMessage = _.after(saves.length, function () {
console.log("Done saving!");
});
_.forEach(saves, function () {
console.log("Doing other things.");
logTheFirst2();
completionMessage();
});
// Doing other things. (1)
// Logging the save.
// Doing other things. (2)
// Logging the save.
// Doing other things. (3)
// Done saving!
* If you like the format, I have similar posts for the Array.prototype and the String.prototype.
Links
Other things to read
Popular
- Reveal animations on scroll with react-spring
- Gatsby background image example
- Extremely fast loading with Gatsby and self-hosted fonts