ES6+beginner
Array.from and Array-Like Objects
Converting iterables and array-like objects (things with a length and indices but no array methods) into real arrays, optionally with a mapping function.
Array.from converts anything iterable or array-like into a real array.
Array.from is like a customs officer who accepts either a passport (a genuine iterable) or, failing that, a numbered ticket stub with a stated headcount (an array-like's length and indices) — either way, everyone gets issued a real visitor badge (a genuine Array) with full building access afterward.
Key Concepts
1
Array.from('hello'); // ['h','e','l','l','o']
Array.from(new Set([1, 2])); // [1, 2]
Array.from(document.querySelectorAll('div'));
Array.from(arguments);2
Array-like means it has length and indices, and no array methods.
const arrayLike = { 0: 'a', 1: 'b', length: 2 };
Array.from(arrayLike); // ['a', 'b']
[...arrayLike]; // TypeError -- not iterablelength
3
That is the difference from spread: Array.from handles both array-like and iterable; spread handles only
iterable.
Array.from
4
Which is why Array.from(arguments) works and [...arguments] also works — arguments happens to be both
— while a plain {0:..., length:...} object needs Array.from.
Array.from(arguments)[...arguments]arguments{0:..., length:...}Array.from
5
The second argument is a map function.
Array.from({ length: 5 }, (_, i) => i); // [0,1,2,3,4]
Array.from({ length: 5 }, (_, i) => i * i); // [0,1,4,9,16]
Array.from(nodeList, el => el.textContent);6
Array.from({ length: n }, fn) is the idiomatic way to build a range, and it is better than the
alternatives:
Array.from({ length: n }, fn)
7
new Array(5) // holes -- map and forEach SKIP them
new Array(5).fill(0).map(...) // works, two passes
Array.from({length: 5}, ...) // one pass, no holes8
The first one is the trap: new Array(5).map((_, i) => i) returns five holes, because map does not visit
empty slots.
new Array(5).map((_, i) => i)map
9
Where array-likes come from.
arguments
document.querySelectorAll (a NodeList)
getElementsByClassName (an HTMLCollection -- and live)
a regex match result
strings, via index and length10
Array.from copies, which is what you usually want with a live collection.
const els = document.getElementsByClassName('x'); // live
for (const el of Array.from(els)) el.remove(); // safeArray.from
11
Iterating the live collection while removing skips elements, because the collection shrinks underneath the
loop. Copying first avoids it.
12
Array.of is the related one.
new Array(3) // [empty x 3] -- a length, not an element
Array.of(3) // [3]Array.of
13
Which exists because new Array treats a single numeric argument specially.
new Array
14
What the interviewer is probing.1. "What makes something array-like?" Probing: the definition. Stalls: "It looks like an
array." Moves up: it has a length and indexed properties but no array methods — arguments and a
NodeList are the usual examples.
15
2. "What can Array.from do that spread cannot?" Probing: the difference. Stalls: "Nothing."
Moves up: it converts array-like objects that are not iterable, and takes a mapping function as a
second argument.
16
3. "How do you create a range?" Probing: the idiom. Stalls: "A for loop." Moves up:
Array.from({ length: n }, (_, i) => i), which uses the length property and the map callback
together.
17
4. "Why does Array(5).map not work as expected?" Probing: sparse arrays. Stalls: "It
should." Moves up: the array has holes rather than undefined values, and map skips holes —
Array.from or fill avoids it.