Arrays & Iterables
Array-like Objects & Array.from
Master Array-like conversions in JavaScript. Learn what makes an object array-like, and how to convert it to a true array using Array.from and spread syntax.
1. Introduction
In JavaScript, several built-in APIs return collections of elements that look and behave like arrays but lack array prototype methods. These collections are known as Array-like Objects. To run array operations (like map or filter) on them, you must first convert them into true arrays.
2. Why It Matters
Common structures like DOM query results (NodeList, HTMLCollection) or function arguments (the legacy arguments object) are array-like. Attempting to call array methods on them directly throws runtime errors.
3. Real-World Analogy
Think of a Set of Toy Building Blocks:
- Array-like Object (Decorative Display Blocks): Blocks glued to a display stand. They look like individual blocks and are organized in order, but you cannot separate them, connect them to other blocks, or rebuild them into a different structure.
- True Array (Standard Blocks Container): Loose building blocks in a box. You can pick them up, combine them, swap their order, and rebuild them however you want (use array methods). Converting array-like objects is like ungluing the display blocks so they can be used as loose building blocks.
4. Defining Array-like Objects
An object is considered array-like if it satisfies two requirements:
1. It has a non-negative integer length property.
2. It has indexed properties (numeric keys starting at 0).
5. Conversion Strategies
You can convert array-like structures to true arrays using three methods:
1. Array.from:
Converts array-like or iterable objects to true arrays. It also accepts an optional map function argument to transform elements during conversion.
2. Spread Operator:
Unpacks elements into an array literal. Note: This requires the object to be iterable (implement the iterable protocol), which custom array-like objects without an iterator function do not support.
6. Practical Example
This script demonstrates converting the legacy arguments object to run array transformations:
7. Common Mistakes
- Using the spread operator on custom array-like objects: The spread operator requires the object to be iterable. Custom array-like objects that lack an iterator function throw a TypeError if spread directly:
[...arrayLike]. UseArray.from(arrayLike)instead.
8. Quick Quiz
Q1: Which method should you use to convert a custom array-like object that lacks an iterator function into a true array?
A) The spread operator [...arrayLike]
B) Array.from(arrayLike)
Answer: B — Array.from() works on any object containing a length property and indexed elements, even if it does not implement the iterator protocol.
9. Scenario-Based Challenge
The DOM Node filter:
You query DOM nodes: const items = document.getElementsByClassName('active'). You need to filter out elements that lack a data-attribute key. Write a converter that filters this list safely.
10. Debugging Exercise
Explain why this spread operation throws a TypeError, and how to fix it:
const config = { 0: 'light', 1: 'dark', length: 2 };
const copy = [...config]; // throws TypeError: config is not iterable!
View Solution
Diagnosis: The spread operator requires the target object to implement the iterator protocol (have a [Symbol.iterator] property). Standard object literals do not have one, even if they have indexed properties and a length.
Fix: Use Array.from() instead of the spread operator:
const copy = Array.from(config); // ['light', 'dark']
11. Interview Questions
🟢 Q1: What makes an object "array-like" in JavaScript, and what are the two main ways to convert it into a true array?
Answer: An object is array-like if it has a non-negative integer length property and indexed elements (properties with keys "0", "1", etc.).
The two main ways to convert it are:
1. Array.from(arrayLike): Works on any array-like object by inspecting the length and indexed elements.
2. The spread operator ([...arrayLike]): Works only if the array-like object also implements the iterable protocol (e.g. NodeList or arguments).
12. Production Considerations
- • Array.from Mapping: When converting and mapping values, prefer using
Array.from(arrayLike, mapFn)overArray.from(arrayLike).map(mapFn). The second parameter maps elements during conversion, avoiding the creation of an intermediate array in memory.