Lodash _.sum() method

Beginner
⏱️ 6 min read
📚 Updated: May 2026
🎯 3 Code examples
🚀 3 Try-it labs
Lodash

What you’ll learn

  • How _.sum is implemented as (array && array.length) ? baseSum(array, identity) : 0—why it’s a one-liner with surprising edge cases.
  • The friendly empty-input guard: _.sum([]), _.sum(null), _.sum(undefined) all return 0.
  • The string-concatenation trap: a single string in the array can turn the result into a concatenated string.
  • How baseSum skips undefined elements, coerces null to 0, and lets NaN poison the result.
  • That _.sum works with all-BigInt arrays but throws on mixed BigInt/Number, and never fixes floating-point precision.

Prerequisites

Take a quick look at _.add() (pairwise) and _.mean() (which shares baseSum). Knowing how the + operator coerces strings vs numbers will save you a lot of head-scratching.

  • JavaScript + coercion: if either operand is a string, the result is a string. This is what makes _.sum([1, "2"]) behave unexpectedly.
  • Float arithmetic: 0.1 + 0.2 !== 0.3. Lodash does not correct this.

Overview

The whole source is: function sum(array) { return (array && array.length) ? baseSum(array, identity) : 0; }. baseSum walks the array and, for every element where iteratee(value) !== undefined, runs result === undefined ? current : (result + current). That single line of logic explains every quirk on this page: the first non-undefined value seeds the accumulator without coercion, subsequent values are folded with native +, and undefined is silently skipped.

Empty → 0

Length-check guard: empty array, null, and undefined all return 0.

String poisoning

A single string in the array switches + to concat. The result becomes a string, not a number.

No precision fix

_.sum([0.1, 0.2, 0.3]) is 0.6000000000000001. Lodash just wraps native +.

Syntax

javascript
_.sum(array)
  • array (Array): the array to iterate over.
  • Returns (number): the sum. 0 for empty, null, or undefined input. May be a string if any element is a string (see Example 2). May be NaN if any element is NaN.
  • Want a key/iteratee? Use _.sumBy() instead—_.sum takes no second argument and silently ignores it.
1

Basics — clean arrays and the empty guard

The docs example, a few common shapes, and the friendly empty-input behaviour. Notice that null and undefined arrays don’t throw the way native reduce would.

javascript
import sum from "lodash/sum";

console.log(sum([4, 2, 8, 6]));      // 20   (docs example)
console.log(sum([1, 2, 3, 4, 5]));   // 15

// Floating-point reality: Lodash does NOT fix precision
console.log(sum([0.1, 0.2, 0.3]));   // 0.6000000000000001

// Friendly guard for missing input
console.log(sum([]));                 // 0
console.log(sum(null));               // 0
console.log(sum(undefined));          // 0

// Larger array via Array.from + range
const ints = Array.from({ length: 100 }, (_, i) => i + 1);
console.log(sum(ints));               // 5050
Try it Yourself
2

The string-concatenation trap

Because baseSum uses native +, a single string is enough to flip the entire operation from arithmetic to concatenation. The result’s type changes too—you get back a string, not a number. Coerce with Number() or arr.map(Number) before calling.

javascript
import sum from "lodash/sum";

// String poison: one string flips '+' to string concat
const dirty = [1, "2", 3];
const total = sum(dirty);
console.log(total);                  // "123"      (string!)
console.log(typeof total);           // "string"

// Single-string array passes through unchanged (no coercion happens)
console.log(sum(["42"]));            // "42"       (still a string)

// null coerces to 0, undefined is silently skipped
console.log(sum([1, null, 3]));      // 4
console.log(sum([1, undefined, 3])); // 4

// NaN poisons everything
console.log(sum([1, NaN, 3]));       // NaN

// Fix: coerce to numbers first
console.log(sum(dirty.map(Number))); // 6
// Caveat: Number("oops") is NaN, which still poisons. Filter junk first if needed.
Try it Yourself
3

Infinity, BigInt, and array-likes

A grab-bag of edge cases that matter in production. Infinity propagates, opposite infinities give NaN, BigInt works only when every element is a BigInt, and _.sum happily accepts array-likes with a length.

javascript
import sum from "lodash/sum";

// Infinity propagation
console.log(sum([1, Infinity, 2]));        // Infinity
console.log(sum([Infinity, -Infinity]));   // NaN

// Overflow to Infinity
console.log(sum([Number.MAX_VALUE, Number.MAX_VALUE])); // Infinity

// BigInt: works when ALL elements are BigInt
console.log(sum([1n, 2n, 3n]));            // 6n

// Mixed BigInt + Number: throws
try {
  console.log(sum([1n, 2]));
} catch (err) {
  console.log("Threw:", err.message);      // "Cannot mix BigInt and other types..."
}

// Array-likes work too (length-based iteration)
console.log(sum({ length: 3, 0: 10, 1: 20, 2: 30 })); // 60

// Common reporting helper
const orders = [
  { id: 1, total: 49.99 },
  { id: 2, total: 12.50 },
  { id: 3, total: 30.00 }
];
console.log(sum(orders.map(o => o.total))); // 92.49
// (Or use _.sumBy(orders, "total") in one call.)
Try it Yourself

📋 _.sum vs native alternatives

Input_.sum(arr)arr.reduce((a,b) => a+b, 0)Notes
[4, 2, 8, 6]2020Identical.
[]00Both return 0.
null / undefined0throwsLodash adds a friendly guard; reduce needs ?. or a null-check.
[1, "2", 3]"123" (string)"0123" (string)Both poisoned by string concat. The reducer’s seed 0 still concats once a string arrives.
[1, undefined, 3]4NaNLodash skips undefined; reduce does 1 + undefined.
[1, null, 3]44Both treat null as 0.
[0.1, 0.2, 0.3]0.6000…10.6000…1Same float-precision result.
[1n, 2n, 3n]6nthrows on seed 0Lodash seeds with the first element (BigInt). The reducer needs a BigInt seed (e.g. 0n).

Pitfalls to avoid

Strings

One string poisons the sum

_.sum([1, "2", 3]) returns "123", not 6—and the type changes to string. Coerce with arr.map(Number) before summing if the data is untyped.

NaN

Poisons everything

A single NaN turns the sum into NaN. Filter with arr.filter(Number.isFinite) first if junk values are possible.

Precision

Not a precision fix

_.sum([0.1, 0.2]) is 0.30000000000000004. The old reference’s “use Lodash for financial calculations” framing is misleading—scale to integer cents (or use decimal.js) for money.

Second arg

No iteratee, silently ignored

_.sum(orders, "total") ignores the second argument and sums the array’s objects—giving you a useless string. Use _.sumBy().

BigInt

All-or-nothing

All-BigInt arrays work and return a BigInt. Mixing with Number throws Cannot mix BigInt and other types.

❓ FAQ

Different guards. _.sum is wrapped in (array && array.length) ? baseSum(...) : 0, so empty, null, and undefined all short-circuit to 0. _.mean has no such guard — it computes baseSum / array.length, which becomes 0 / 0 = NaN for an empty array. If you want NaN on empty input, check before calling: arr.length ? _.sum(arr) : NaN.
baseSum uses the native + operator. The first element 1 seeds the result. When it hits '2', 1 + '2' is the string '12' (JS coerces to string when either operand is a string). Then '12' + 3 is '123'. To avoid this, coerce first: _.sum(arr.map(Number)) — but be aware that turns non-numeric strings into NaN, which then poisons the sum.
No. _.sum([0.1, 0.2, 0.3]) returns 0.6000000000000001, exactly like 0.1 + 0.2 + 0.3. Lodash just calls native +. For money, scale to integer cents first (sum then divide), or use a decimal library like decimal.js.
undefined elements are skipped (baseSum's if (current !== undefined) check). null coerces to 0 (so _.sum([1, null, 3]) is 4, same as if the null were 0). NaN is a real number to JS, so it poisons the result — a single NaN makes the whole sum NaN.
Yes, if every element is a BigInt: _.sum([1n, 2n, 3n]) returns 6n. The first element seeds with the BigInt and subsequent + operations are BigInt + BigInt, which is legal. Mixing BigInt with Number throws Cannot mix BigInt and other types — same as native +.
Three: (1) _.sum returns 0 for null/undefined arrays (reduce throws); (2) _.sum skips undefined elements (reduce includes them, producing NaN once you hit one); (3) reduce with initial 0 forces numeric arithmetic (so [1, '2'].reduce((a, b) => a + b, 0) is '012'). The native reducer's seed of 0 prevents the lone-string passthrough.

Summary

  • Purpose: add every value in an array—baseSum(array, identity) when non-empty, 0 otherwise.
  • Remember: empty/null/undefined → 0; undefined elements skipped; null0; one string poisons to concat; NaN poisons; all-BigInt works (mixed throws); precision unfixed.
  • Next: Lodash _.sumBy(), or read the official Lodash docs for _.sum.
Did you know?

_.sum([]) returns 0not NaN like _.mean([]). Lodash short-circuits with (array && array.length) ? baseSum(array, identity) : 0, so empty arrays, null, and undefined all give back the same friendly 0. The flip side: a single string poisons the result—_.sum([1, "2", 3]) returns the string "123", not 6.

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

6 people found this page helpful