Convert Array-Like Objects Using Array.from in JS
This article explores how JavaScript’s Array.from()
method transforms array-like objects into genuine arrays. You will learn
what defines an array-like object, the internal mechanism
Array.from() uses to perform the conversion, practical
implementation examples, and how to utilize its secondary mapping
argument for inline element transformation.
What Is an Array-Like Object?
An array-like object is any JavaScript object that meets two specific
criteria: 1. It possesses a non-negative integer length
property. 2. Its elements are indexed using numeric keys (starting from
0 up to length - 1).
Common examples in JavaScript include the arguments
object inside functions, DOM collections like NodeList or
HTMLCollection, and custom objects structured with indexed
properties. Unlike true arrays, array-like objects do not inherit
methods from Array.prototype, such as .map(),
.filter(), .reduce(), or
.forEach().
The Mechanism of
Array.from()
Introduced in ECMAScript 2015 (ES6), Array.from()
creates a new, shallow-copied Array instance from an
iterable or array-like object.
When applied to an array-like object, Array.from()
executes the following internal steps: 1. Reads the
length property: It determines the size of the
target array by accessing obj.length. If the length is
negative, missing, or invalid, it defaults to 0. 2.
Iterates through indices: It loops from index
0 up to length - 1. 3. Retrieves
values: For each index, it accesses the corresponding property
on the object (obj[index]). If an index is missing, it
returns undefined. 4. Constructs the
array: It populates a newly allocated array with these values
and returns it.
Basic Conversion Example
Consider a custom array-like object:
const arrayLike = {
0: 'apple',
1: 'banana',
2: 'cherry',
length: 3
};
const realArray = Array.from(arrayLike);
console.log(realArray);
// Output: ['apple', 'banana', 'cherry']
console.log(Array.isArray(realArray));
// Output: trueOnce converted, full array functionality is available:
realArray.push('dragonfruit');
const upperCase = realArray.map(item => item.toUpperCase());
console.log(upperCase);
// Output: ['APPLE', 'BANANA', 'CHERRY', 'DRAGONFRUIT']Handling Missing Indices and Edge Cases
If the length property specifies a number greater than
the actual indexed properties present, Array.from() fills
the missing slots with undefined:
const sparseObject = {
0: 'first',
2: 'third',
length: 3
};
const result = Array.from(sparseObject);
console.log(result);
// Output: ['first', undefined, 'third']If the length property is smaller than the available
indices, only elements up to length - 1 are included:
const truncatedObject = {
0: 'a',
1: 'b',
2: 'c',
length: 2
};
console.log(Array.from(truncatedObject));
// Output: ['a', 'b']Using the Built-In Map Function
Array.from() accepts an optional second argument: a
mapping function (mapFn). This allows you to transform
elements during the array creation process, avoiding the performance
overhead of creating an intermediate array before calling
.map().
Syntax:
Array.from(arrayLike, (element, index) => { /* transformation */ });Example:
const numbers = {
0: 10,
1: 20,
2: 30,
length: 3
};
const doubled = Array.from(numbers, value => value * 2);
console.log(doubled);
// Output: [20, 40, 60]You can also use this feature to quickly generate initialized sequences:
const sequence = Array.from({ length: 5 }, (_, index) => index + 1);
console.log(sequence);
// Output: [1, 2, 3, 4, 5]Summary
Array.from() bridges the gap between indexed data
structures and standard JavaScript arrays. By inspecting the
length property and iterating through the sequential keys,
it produces a fully functional array, unlocking standard array methods
and streamlining data manipulation.