RangError:为函数调用提供了太多参数

时间:2018-10-23 12:12:46

标签: javascript html xpath

我有一个很好的解决方案,可以从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-

3 个答案:

答案 0 :(得分:1)

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

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

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

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

答案 1 :(得分:1)

有关使用apply合并数组的信息,请参见此评论in MDN docs

  

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

apply page中的另一条注释:

  

但是要注意:以这种方式使用应用时,存在冒超出JavaScript引擎参数长度限制的风险。应用带有太多参数(想想成千上万个参数)的函数的结果因引擎而异(JavaScriptCore的硬编码参数限制为65536),因为该限制(甚至包括任何过大堆栈的性质)行为)未指定。一些引擎将引发异常。更有害的是,其他人将任意地限制实际传递给应用函数的参数数量。为了说明后一种情况:如果这样的引擎有四个参数的限制(实际上的限制当然要高得多),则好像在上面的示例中通过了参数5、6、2、3一样,而不是整个数组。

答案 2 :(得分:0)

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

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

问题顶部发布的原始函数在函数内部声明了arr。因此,每个递归调用都有其自己的本地数组。在具有很多个注释节点的文档中,它仍然可能会出现“范围错误”。