最近我遇到了一个问题:传递给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()
并不安全,而且所有......我愿意接受建议!
答案 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文字解析器,我想你必须自己编写它......虽然你输入这么长时间它可能会非常慢。