【发布时间】:2020-12-29 12:14:12
【问题描述】:
几年来,我一直在构建和使用 JavaScript 中的自定义数据分析工具(repo、docs)。
我最近所做的更改之一是使用 JavaScript 类来扩展本机 Array 类型,因此我可以轻松地将我的自定义函数调用为类数组对象上的方法,而不是将它们传递给那些用作参数,而不会失去使用 [] 表示法访问元素的能力。
为此,我一直在使用以下代码:
class AnalyserRows extends Array {
constructor(sourceArray) {
super(...sourceArray);
}
// ...
}
这已经运行了一段时间,但最近我尝试加载特别大的数据集,但遇到了问题。我试图创建一个包含大约 66,000 个元素的 AnalyserRows 对象,但 Chrome 会抛出此错误:
未捕获的 RangeError:超出最大调用堆栈大小
在我的搜索中,我发现了这个问题的解释: RangeError - Maximum Call Stack Size Exceeded Error Using Spread Operator in Node.js / Javascript
扩展运算符(和 Array.assign)将整个源数组加载到堆栈中,然后将其推送到目标数组中。一旦源数组超过 125,052,就会导致堆栈溢出/范围错误。
所以现在我的问题是如何在自定义类的 constructor 中调用 super 并在不使用扩展运算符的情况下传递源数组的每个元素?
可以创建一个包含这么多元素的Array 而没有任何真正的问题,所以我觉得应该可以用像这样扩展Array 的类来做同样的事情。但是如果不使用扩展运算符或进行一些其他更改以阻止我使用我一直在使用的某些语法,我不知道该怎么做。
【问题讨论】:
-
你是怎么打电话给
AnalyserRows的?顺便说一句I doubt this subclass works at all. -
“rows”是一个现有的数组,我这样称呼它:
dataConfig.rows = new AnalyserRows(rows);它确实有效。在遇到这个问题之前,我已经使用了很长时间。现在刚刚检查,我可以调用常规的Array方法,如map和reduce没问题。 -
也许你也定义了
static [Symbol.species] = Array? -
不。我知道只有当您希望
Array的本机方法通常返回一个新的Array(如map和reduce)仍然返回一个Array时才需要这样做。我不想那样。如果您有兴趣查看代码,我将链接到我的问题中的 repo。有问题的文件是 analyser.js -
通过扩展语法调用,
new AnalyserRows([]).map(x => x)确实为我抛出了TypeError: Found non-callable @@iterator- 就像在链接的问题中一样。使用super(sourceArray.length),它将返回AnalyserRows [undefined](长度为1),因为您将undefined传递给超级调用。不知道为什么不能重现?
标签: javascript es6-class spread-syntax