What you’ve shown is equivalent to this (except this goes beyond five elements, but also beyond one in the other direction):
return this.result = Array.from({
length: Math.floor(this.foo)
}, (_value, index) => ({
year: index + 1
}));
This assumes that this statement is inside a function (otherwise, return
wouldn’t work).
A more reasonable length may be Math.max(0, Math.min(2 ** 32 - 1, Math.floor(this.foo)))
which clamps1 the length to at least 0 and at most 232 − 1, the maximum Array length.
If you want to always have at least one element in your array, then use Math.max(1,
…)
instead.
Returning an assignment (i.e. return this.result =
…;
) is frowned upon.
The best practice is to separate these statements2:
this.result = Array.from({
length: Math.max(0, Math.min(2 ** 32 - 1, Math.floor(this.foo)))
}, (_value, index) => ({
year: index + 1
}));
return this.result;
Array.from
is used with both arguments: the first one is the “array-like” object { length: Math.max(0, Math.min(2 ** 32 - 1, Math.floor(this.foo))) }
which gets converted to a proper Array
object.
In this case, an array with a length of Math.floor(this.foo)
is initialized (clamped to the range of possible Array lengths).
The second argument maps each value at a certain index
to an object with the year
property with the value index + 1
.
_value
isn’t used (it’s undefined
anyway).
The advantage to use Array.from(
array-like,
mapping-function)
over e.g. .fill().map(
…)
is that only a single array is created in memory.
Array(
…).fill().map(
…)
creates two new arrays: the first one at Array(
…).fill()
, the second one at .map(
…)
.
Therefore, the Array.from
approach is more memory-efficient.
1: Maybe soon we’ll finally get a Math.clamp
method…
2: Technically, this would be equivalent.
If this.result
is a getter / setter, there may be an observable difference.
const result = Array.from({
length: Math.max(0, Math.min(2 ** 32 - 1, Math.floor(this.foo)))
}, (_value, index) => ({
year: index + 1
}));
this.result = result;
return result;