JS Tip of the Day: Array-likes

Array-likes
Level: Intermediate

The term array-like is used to describe an object that is not an array but can be treated like one. Array-likes use indexed properties (0, 1, 2, etc.), and have a length property.

let basicArrayLike = { length: 0 };

Some built-in types in JavaScript are already array-likes, for example strings. Strings are not arrays, but they have a length property and allow you to access individual characters by index much like an array.

let hello = 'hello';
console.log(hello.length); // 5 (is array-like)
console.log(hello[0]); // h
console.log(hello[1]); // e
console.log(hello[2]); // l
// etc.

Other built-in array-likes include: typed arrays, the arguments object, and HTML collections and node lists within the web API.

There are a number of functions or methods that can not only work on arrays but also with array-likes. One you might have used is Array.from(). This converts any iterable or array-like into a new array.

let basicArrayLike = { length: 3 };
let basicArray = Array.from(basicArrayLike);
console.log(Array.isArray(basicArrayLike)); // false
console.log(Array.isArray(basicArray)); // true
console.log(basicArray); // [undefined, undefined, undefined]

Most array instance methods are also designed in a generic way specifically so that they can work not just on arrays, but array-likes as well.

let { push, map } = Array.prototype;
let fakeArray = { push, map, length: 0 }; // array-like
fakeArray.push(1, 2, 3);
console.log(fakeArray); // {'0': 1, '1': 2, '2': 3, length: 3}
let doubled = fakeArray.map(x => x * 2);
console.log(doubled); // [2, 4, 6]

Something similar was often done before Array.from() to convert arguments objects (array-likes) to arrays by calling array slice() on them. This created an array copy of the arguments object that had all of the array methods built-in making it easier to work with.

function someFunction () {
    let argsArray = Array.prototype.slice.call(arguments);
    // ...
}

Because methods like push, map and slice seen above (as well as most of the others found in normal arrays) don’t require that the object they’re being used be an actual array, they can be very useful for providing their functionality to any kind of non-array indexed collection.

More info: