Lodash concat: Merging Different Data Types

The _.concat method in the Lodash JavaScript library creates a new array by concatenating an initial array with additional values or arrays. While it processes multiple data types seamlessly within a single call, its behavior varies depending on whether an argument is a primitive value, an object, or another array. This guide explains how _.concat handles primitives, reference objects, single-level arrays, and nested structures, detailing its shallow flattening mechanics and reference-copying behavior.

Core Behavior and Immutability

The signature for the method is _.concat(array, [values]). Lodash's _.concat is an immutable operation: it does not modify the original array or any arrays passed as arguments. Instead, it creates and returns a shallow copy containing all combined elements. If the first argument is not an array (or is null/undefined), Lodash casts it into an array format before appending subsequent values.

Merging Primitives

Primitives—such as numbers, strings, booleans, null, undefined, and symbols—are appended directly into the resulting array as individual elements without alteration.

const base = [1];
const result = _.concat(base, 2, 'three', true, null, undefined);

// Output: [1, 2, 'three', true, null, undefined]

Each primitive value occupies its own sequential index in the new array immediately following the base elements.

Merging Arrays (One-Level Shallow Flattening)

When an array is passed to _.concat, Lodash automatically unwraps (flattens) it by exactly one level. The elements inside the passed array are extracted and appended individually.

const base = [1, 2];
const result = _.concat(base, [3, 4], [5]);

// Output: [1, 2, 3, 4, 5]

Merging Nested Arrays

The flattening behavior of _.concat only applies to the first depth level. Multi-dimensional or nested arrays preserve their inner structures:

const base = [1];
const nested = [[2, 3], [4, [5]]];
const result = _.concat(base, nested);

// Output: [1, [2, 3], [4, [5]]]

In this example, the outer array nested is stripped, but [2, 3] and [4, [5]] remain intact as distinct array elements within the output.

Merging Objects and Functions

Plain objects, functions, dates, and regular expressions are non-array reference types. Unlike arrays, they are not flattened or spread; they are appended as discrete items.

Because _.concat performs a shallow copy, objects are copied by reference, not by value.

const user = { name: 'Alice' };
const base = [{ id: 1 }];

const result = _.concat(base, user, { role: 'admin' });
// Output: [{ id: 1 }, { name: 'Alice' }, { role: 'admin' }]

// Modifying the original object affects the element in the merged array
user.name = 'Bob';
console.log(result[1].name); // 'Bob'

Mutating any nested property of an object passed to _.concat will reflect across both the original object and the new array.

Merging Mixed Data Types Simultaneously

_.concat accepts an arbitrary number of arguments containing different data types in any order. Each argument is evaluated according to its specific type rules:

const base = ['start'];
const mixed = _.concat(
  base,
  100,                  // Primitive: appended directly
  ['a', 'b'],           // Array: unwrapped one level
  { type: 'item' },     // Object: appended as reference
  [['nested']]          // Nested Array: unwrapped one level, inner array preserved
);

// Output: ['start', 100, 'a', 'b', { type: 'item' }, ['nested']]

In summary, _.concat treats arrays as lists of items to unpack once, while all other data types (primitives, plain objects, functions) are appended directly as single items.