【问题标题】:RangError: too many arguments provided for a function callRangError:为函数调用提供的参数过多
【发布时间】:2019-03-27 16:16:45
【问题描述】:

我有一个很好的解决方案来从 HTML 节点树中获取 HTML 注释

var findComments = function(el) {
    var arr = [];
    for (var i = 0; i < el.childNodes.length; i++) {
        var node = el.childNodes[i];
        if (node.nodeType === 8) {
            arr.push(node);
        } else {
            arr.push.apply(arr, findComments(node));
        }
    }
    return arr;
};

var commentNodes = findComments(document);

// whatever you were going to do with the comment...
console.log(commentNodes[0].nodeValue);

来自this thread。 我所做的就是添加这个小循环来打印所有节点。

var arr = [];
var findComments = function(el) {

    for (var i = 0; i < el.childNodes.length; i++) {
        var node = el.childNodes[i];
        if (node.nodeType === 8) {
            arr.push(node);
        } else {
            arr.push.apply(arr, findComments(node));
        }
    }
    return arr;
};
var commentNodes = findComments(document);

//I added this

for (var counter = arr.length; counter > 0; counter--) {
    console.log(commentNodes[counter].nodeValue);
}

我不断收到此错误消息:

RangeError:为函数调用调试器提供的参数过多 评估代码:9:13

编辑:我在粘贴时有一个拼写错误,将代码从 i-- 更改为 counter--

【问题讨论】:

  • 在您添加的for 循环中,您在测试表达式中使用变量counter,但它以i-- 结尾;应该是counter--
  • 另外,由于某种原因,您将 arr 的声明从函数外部移到了内部;可能不是一个好主意。 edit 事实上,这几乎肯定是导致您的 Range Error 的原因。
  • @choz 这个想法可能是得到一个平面数组; push 数组会产生一个数组数组。
  • 你将arr初始化移到循环外,可能使用arr.length而不是commentNodes.length
  • 再次OP,问题是您将arr的声明从函数内部移到了外部。

标签: javascript html xpath


【解决方案1】:

关于使用apply 合并数组的评论见in MDN docs

如果第二个数组(示例中为 moreVegs)非常大,则不要使用此方法,因为实际上一个函数可以采用的最大参数数量是有限的。有关详细信息,请参阅 apply()。

来自apply page的另一条笔记:

但请注意:以这种方式使用 apply 时,可能会超出 JavaScript 引擎的参数长度限制。应用带有太多参数的函数(考虑超过数万个参数)的后果因引擎而异(JavaScriptCore 的硬编码参数限制为 65536),因为限制(实际上甚至是任何过大堆栈的性质行为)未指定。有些引擎会抛出异常。更有害的是,其他人会任意限制实际传递给应用函数的参数数量。为了说明后一种情况:如果这样的引擎有四个参数的限制(实际限制当然要高得多),就好像参数 5、6、2、3 已被传递以应用于上面的示例,而不是整个数组。

【讨论】:

    【解决方案2】:

    由于数组从索引0开始,实际上数组中的最后一项是arr.length - 1

    您可以通过以下方式修复它:

    for (var counter = arr.length - 1; counter >= 0; counter--)
    

    请注意,我添加了 arr.length -1counter &gt;= 0,因为零是数组的第一个索引。

    【讨论】:

    • 这是真的,但这不是导致Range Error 的原因。
    【解决方案3】:

    添加 for 循环并不是您唯一更改的内容(请参阅有关修复该循环的其他答案)。您还将arr 的声明从函数内部移到外部,使arr 相对全局。

    因此,每次对findComments() 的递归调用都在相同的数组 上工作,而.apply() 调用每次都会将整个内容推回到数组的末尾。一段时间后,它的长度超过了运行时的限制。

    您问题顶部发布的原始函数在函数内部声明了arr。因此,每个递归调用都有自己的本地数组可供使用。但是,在具有 很多 注释节点的文档中,它仍然可能出现 Range Error。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-28
      • 2019-06-20
      • 2018-05-15
      • 1970-01-01
      • 2022-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多