Converting Array-Like Objects to Arrays in JavaScript
Array-like objects in JavaScript possess numeric indices and a length property, yet lack native array methods such as map, filter, or forEach. Common examples include the arguments object inside functions and DOM collections returned by document.querySelectorAll.
An array-like structure typically looks like this:
const collection = {
0: 'alpha',
1: 'beta',
2: 'gamma',
length: 3
};
While you can access elements via bracket notation and iterate using a standard for loop, invoking array methods directly results in errors.
Legacy Conversion Techniques (ES5)
Before modern syntax, developers relied on manual iteration or prototype manipulation.
Manual Iteration
The most explicit approach involves creating a new array and populating it manually:
function toRealArray(source) {
const output = [];
for (let idx = 0; idx < source.length; idx++) {
output.push(source[idx]);
}
return output;
}
function processData() {
const args = toRealArray(arguments);
console.log(args);
}
processData('x', 'y', 'z');
// ['x', 'y', 'z']
Slice Method
A more concise technique leverages Array.prototype.slice:
function processData() {
const args = Array.prototype.slice.call(arguments);
console.log(args);
}
processData(10, 20, 30);
// [10, 20, 30]
Though functional, this approach obscuers intent and requires understanding of this binding in JavaScript.
Modern Approach (ES6)
ES6 introduced Array.from(), designed specifically for converting iterable and array-like objects into proper arrays.
function processData() {
const args = Array.from(arguments);
console.log(args);
}
processData('a', 'b', 'c');
// ['a', 'b', 'c']
Mapping During Conversion
Array.from() accepts an optional mapping function as its second argument, applying a transformation to each element during creation without requiring a separate map() call:
const squares = Array.from({length: 4}, (_, i) => i * i);
console.log(squares);
// [0, 1, 4, 9]
Binding Context
The third argument specifies the this value for the mapping function:
const calculator = {
multiplier: 2,
compute(n) {
return n * this.multiplier;
}
};
function transform() {
return Array.from(arguments, calculator.compute, calculator);
}
const results = transform(5, 10, 15);
console.log(results);
// [10, 20, 30]
String Conversion
Array.from() also splits strings into character arrays:
const chars = Array.from('hello');
console.log(chars);
// ['h', 'e', 'l', 'l', 'o']
This method provides a cleaner, more readable alternative to legacy conversion techniques while offering built-in mapping capabilities.