Array.from()

Creates a new array from an iterable or array-like object, optionally mapping each value as it goes.

Signature
Array.from(items)
Array.from(items, mapFn)
Array.from(items, mapFn, thisArg)
  • Added in JavaScript ES2015

Parameters

ParameterTypeDescription
$itemsIterable | ArrayLikeAn iterable (anything with a [Symbol.iterator] method, such as a string, Set, Map or generator) or an array-like object (anything with a length property and indexed elements).
$mapFnoptional(element: any, index: number) => any= undefinedA function called on every element. Its return value is what gets stored in the new array. It receives only the element and the index — there is no third array argument.
$thisArgoptionalany= undefinedValue to use as this when executing mapFn.

Return value

ArrayA new, shallow-copied Array instance.

Errors

Throws a TypeError if mapFn is supplied and is not callable.

Changelog

  • PHP ES2015Introduced alongside iterators; it is the standard way to consume any iterable eagerly.

Array.from() exists because JavaScript is full of things that behave like arrays without being one. It accepts two distinct shapes of input: iterables — strings, Set, Map, generators, arguments — and array-like objects, meaning any object with a numeric length and index keys. Whichever you hand it, you get back a real array with real array methods.

Reach for it in three situations: draining an iterator into a list you can index and sort; deduplicating with new Set(values) and converting back; and generating sequences from nothing with the { length: n } idiom.

The second argument

Passing mapFn is not just shorthand for a following .map() call — it avoids building an intermediate array, which matters for large inputs and for typed arrays. But the callback is not the same as the one map() takes: it receives (element, index) only. The array is still under construction, so there is no third argument to inspect. Callbacks written against map()'s three-argument shape silently see undefined.

The copy is shallow. Nested objects are shared with the source, so mutating one is visible through the other.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Deduplicate a list by round-tripping it through a Set
  • Build a range like [0, 1, 2, 3, 4] without a loop
  • Turn a Map's entries or a generator's output into a sortable array
  • Convert an arguments object or other array-like into a real array

Frequently asked questions

What is the difference between Array.from() and the spread operator?

Spread ([...value]) only works on iterables, while Array.from() also accepts array-like objects with a length property. Spread throws a TypeError on { length: 3 }; Array.from() returns [undefined, undefined, undefined]. Spread is shorter when you know the input is iterable and takes no map callback.

Why does my Array.from() callback get undefined as the third argument?

Because Array.from()'s mapping function is called with only two arguments, the element and the index. The array is still being constructed, so it is not passed. Only Array.prototype.map() supplies the third array argument.

How do I create an array of numbers from 1 to n?

Use Array.from({ length: n }, (_, i) => i + 1). The { length: n } object is treated as an array-like of n undefined values, and the map callback replaces each one with its index plus one.

More examples

Iterables: strings, Sets and Maps

A string yields one entry per character. A Set yields its values in insertion order, which is why Set round-tripping is the standard dedupe. A Map yields [key, value] pairs, and its .keys() iterator yields just the keys — proof that any iterator, not only a collection, is accepted.

Example · javascript
console.log(Array.from("foo"));

const unique = Array.from(new Set(["a", "b", "a", "c"]));
console.log(unique);

const scores = new Map([["ana", 3], ["bo", 9]]);
console.log(Array.from(scores));
console.log(Array.from(scores.keys()));

Array-like objects and holes

The missing index 1 becomes undefined, not a hole. Array.from() never produces a sparse array: the last line shows index 1 is absent from the sparse literal but present (as undefined) in the copy, so methods like forEach will visit it.

Example · javascript
const arrayLike = { length: 3, 0: "x", 2: "z" };
console.log(Array.from(arrayLike));

// a bare length is enough
console.log(Array.from({ length: 3 }));

// compare with a genuinely sparse array
const sparse = [ , , 5];
console.log(1 in sparse, 1 in Array.from(sparse));

Generating data without a loop

The { length: n } object is the cheapest array-like there is, so it works as a counted loop. Nesting the call builds a matrix where each row is a distinct array — unlike Array(3).fill([]), which would share one row object across all three slots.

Example · javascript
const range = (start, end) =>
  Array.from({ length: end - start }, (_, i) => start + i);
console.log(range(5, 10));

const grid = Array.from({ length: 3 }, (_, r) =>
  Array.from({ length: 3 }, (_, c) => `${r},${c}`),
);
console.log(grid);

Discussion

  • Be the first to comment on this lesson.