in the wild, there exists this pattern to push elements from a source array to a destination array
destinationArray.push(...sourceArray) // ... = spread operator
this pattern is used cos its fast, faster than dst = dst.concat(src)
or dst = [...dst, ...src]
and cos its short, shorter than for (let i = 0; i < src.length; i++) dst.push(src[i])
problem
the source array is limited by the Maximum call stack size
of around 100K in nodejs and 500K in firefox
// problem
[].push(...Array.from({ length: 1000*1000 }))
// Uncaught RangeError: Maximum call stack size exceeded
solution
destinationArray.pushArray(sourceArray)
pushArray, aka: array concat in place, aka: mutable array concat
// array.pushArray polyfill in typescript
(Array.prototype as any).pushArray = function pushArray(...otherList: any[]) {
let c = 0; // count pushed elements
for (let a = 0; a < otherList.length; a++) {
const other = otherList[a];
for (let i = 0; i < other.length; i++) {
this.push(other[i]);
c++;
}
}
return c;
};
(someArray as any).pushArray(otherArray1, otherArray2, [otherItem])
alternatives
using a library, like
import { pushArray } from 'push-array'
pushArray(destinationArray, sourceArray)
but imho this should be a core feature
cost
Array.prototype would become more complex, only to solve a rare edge case
related
sample use case + code transformer
[fix] Maximum call stack size exceeded (#4694) by milahu ยท Pull Request #6716 ยท sveltejs/svelte ยท GitHub
the code transformer could be implemented in eslint