JavaScript函数eval()抛出一个栈外配额异常

时间:2010-09-17 12:53:55

标签: javascript json

最近我遇到了一个问题:传递给eval()函数时有效的JSON导致它抛出错误 - “脚本堆栈空间配额已用完”。

它始终可重复,并且通过初步检查,似乎这是对可定义的对象属性/属性数量的限制(而不是内容的大小)。

以下是示例代码:

function starttest()
{      
       var d = new Array(50000);
       var i = 0;

       for (i = 0; i < d.length; i++) {
            d[i] = new Object();
            d[i].a1 = 1;
            d[i].a2 = 2;
            d[i].a3 = i;
            d[i].a4 = i;
            d[i].a5 = i;
            d[i].a6 = i;
            d[i].a7 = i;
            d[i].a8 = i;
            d[i].a9 = i;
            d[i].a10 = i;
            d[i].a11 = i;
            d[i].a12 = i;
            d[i].a13 = i;
            d[i].a14 = i;
            d[i].a15 = i;
       }       



    var jsonString = JSON.stringify(d);  
    alert(jsonString.length);

    var obj = eval(jsonString);
    var count = 0;
    for( var i = 0; i< obj.length; i++) {

        for (var k in obj[i]) {
            if (obj[i].hasOwnProperty(k)) {
               ++count;
            }
        }
    }

    alert("Done! || Len: " + obj.length + " || " + "Attrib Count: " + count + " || " + typeof obj)
}

有趣的是,我可以定义比代码片段中看到的更多的对象;只有在使用eval()函数时才会出现问题。

对此的任何新见解都会非常有帮助。我知道使用eval()并不安全,而且所有......我愿意接受建议!

3 个答案:

答案 0 :(得分:3)

这意味着它所说的。 eval显然正在使用递归,并且在评估冗长且复杂的JSON文字时,您已超出限制。它适用于JSON.parse(至少在Firefox 3.6.11pre中),这是该作业的正确工具,often faster

答案 1 :(得分:1)

看起来您正在使用JSON类来创建JSON字符串。为什么不使用相反的函数进行stringify以将JSON恢复为对象语法?

http://www.json.org/json_parse.js - 是javsacript JSON类。只需调用json_parse(str);你会得到一个好的对象。

正如你自己所说,eval()并不安全。这是该死的邪恶!

答案 2 :(得分:1)

是的,一般来说这是Firefox的JavaScript解释器的问题。这不只是eval:如果你放五万行:

{a:1,b:2,c:3,d:4,e:5,f:6,g:7,h:8,i:9,j:10,a2:1,b2:2,c2:3,d2:4,e2:5,f2:6,g2:7,h2:8,i2:9,j2:10},

在普通脚本文件或<script>元素中的数组文字中,您会得到完全相同的错误。

脚本块的复杂性似乎受编译时JS_DEFAULT_SCRIPT_STACK_QUOTA的限制。请参阅420869以及相关的链接错误。

在正常情况下,你不太可能遇到这种情况。当然,对于JSON的情况,您可以使用JSON.parse,它不是完整的JavaScript解释器,不受此限制的影响。如果你需要一个不受影响的非有效-JSON JS文字解析器,我想你必须自己编写它......虽然你输入这么长时间它可能会非常慢。