NodeList.prototype.map = Array.prototype.map;
window.list = document.querySelectorAll('div');
window.mapper = node => node.outerHTML;
Array.from(list).map(mapper);
[list].map(mapper);
Array.prototype.map.call(list, mapper);
list.map(mapper);
const result = [];
for (let i = 0; i < list.length; i++)
result.push(mapper(list[i], i, list));
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
Array.from(NodeList).map | |
[...NodeList].map | |
map.call(NodeList) | |
NodeList#map | |
for loop |
Test name | Executions per second |
---|---|
Array.from(NodeList).map | 931745.9 Ops/sec |
[...NodeList].map | 1048340.8 Ops/sec |
map.call(NodeList) | 1084817.5 Ops/sec |
NodeList#map | 1129123.6 Ops/sec |
for loop | 1154181.8 Ops/sec |
Let's dive into the world of JavaScript microbenchmarks.
Benchmark Overview
The provided benchmark tests four different methods for mapping over an HTML NodeList:
Array.from(list).map(mapper)
[...list].map(mapper)
(using spread operator)Array.prototype.map.call(list, mapper)
list.map(mapper)
(directly on the NodeList prototype)Library Used
The benchmark uses the Array.from
method and the map()
function from the Array prototype.
Array.from
is a static method of the Array class, introduced in ECMAScript 2015 (ES6). It creates a new Array instance from an iterable or an array-like object.map()
function is a built-in method of the Array prototype, also introduced in ES6. It creates a new array with the results of applying a provided function to every element in this array.Special JavaScript Feature/Syntax
None, but it's worth noting that the spread operator ([...list]
) is used in two of the benchmarks (2 and 3).
Benchmark Comparison
The four methods being tested have different performance characteristics:
Array.from(list).map(mapper)
: This method creates a new Array instance from the NodeList using Array.from()
, which has an overhead. The map()
function is then applied to this array, resulting in a slow operation.[...list].map(mapper)
: Using the spread operator and applying map()
directly to the NodeList can be faster than creating a new Array instance. However, it may not be as efficient as using Array.prototype.map.call()
.Array.prototype.map.call(list, mapper)
: This method uses the call()
function to invoke map()
on the NodeList prototype, which is likely to be slower than calling map()
directly on an array.list.map(mapper)
: Directly calling map()
on the NodeList prototype can be faster than the other methods, as it avoids the overhead of creating a new Array instance or invoking a function.Pros and Cons
Here's a brief summary of the pros and cons for each method:
Array.from(list).map(mapper)
: Pros: creates a new Array instance that can be reused; Cons: has an overhead, slow.[...list].map(mapper)
: Pros: avoids creating a new Array instance; Cons: may not be as efficient as using Array.prototype.map.call()
.Array.prototype.map.call(list, mapper)
: Pros: uses the optimized map()
function on the NodeList prototype; Cons: likely slower than calling map()
directly.list.map(mapper)
: Pros: avoids overhead of creating a new Array instance or invoking a function; Cons: may not work in older browsers.Other Alternatives
Some other alternatives for mapping over an array-like object like a NodeList include:
forEach()
method instead of map()
, which can be more efficient for small arrays.mapValues
function, which can provide better performance and flexibility.However, it's worth noting that these alternatives may not be as widely supported or optimized as the built-in methods used in the benchmark.