function parseAttach(b)
{
var h="";
for(i=0;i<b.length;i++)
{
var a=b[i];
switch(a['type'])
{
case "image":
h+='<li class="attach aImg" style="background:#000;border-bottom:2px solid #fff"><img style="max-width:425px;max-height:500px" src="http://img.xiami.com/u/phoo/'+a['file']+'"></li>';
break;
case "video":
h+='<li class="attach aVideo" style="background:#f3f3f3"><span class="MxND" f="'+a['from']+'" d="'+a['id']+'"></span></li>';
break;
case "music":
h+='<li class="attach aMusic"><embed src="http://www.xiami.com/widget/0_'+a['id']+'/singlePlayer.swf" type="application/x-shockwave-flash" width="257" height="33" wmode="transparent"></embed></li>';
break;
}
}
return h;
}
一旦上面的函数运行,页面就无法进行交互,那个页面的内存和CPU使用率就会一路飙升。
这是传递给此函数的参数b
的示例:
[{"type":"video","from":"k6","id":"kyxGTZbD-vQ8Domm-eeHiQ"}]
b.length不超过2,此功能执行不超过三次。如果删除此功能,则不会发生内存泄漏。
更新:
按照@GarethMcCaughan的建议,我将警报(i)添加到循环的顶部,它保持警报0,我前往调用代码:
for(i=0;i<c[0].length;i++)//the breakpoint
{
......
if(t[6].length>0)
{
//console.log(t[6].length);
//var a=parseAttach(t[6]);
var a="";
h+='<ul class="attaches">'+a+'</ul>';
}
......
}
正如您在注释中看到的那样,如果我用console.log替换调用,则日志仅显示4次执行。但为什么要重复调用该函数?
然后我发现控制台在循环顶部报告了一个断点(我已将其注释掉),这是函数不断调用的原因吗?
答案 0 :(得分:0)
在你的两个循环中,你没有将var
放在i
变量之前。这意味着它是全球性的。如果它是全局的,则两个循环都使用相同 i
。
for(i=0;i<b.length;i++)
添加var,它应该修复它:
for(var i=0;i<b.length;i++)
编辑:进一步澄清:
for(i=0;i<c[0].length;i++)
{
......
if(t[6].length>0)
{
// THIS CALL WILL SET THE GLOBAL i TO t[6].length
var a=parseAttach(t[6]);
}
......
}
因此,永远不会满足外循环的退出条件,循环的每次迭代都会设置i
,以便i
永远不会到达c[0].length
。
答案 1 :(得分:0)
除了一个bug之外,一切似乎都很好:你忘了将计数器变量i
置于本地。当从循环调用时,代码将重置外部循环的同名计数器变量(为2,因为这是最大长度)并使其永远不会达到其结束条件:
var i; // this variable will always be referenced
function x(number) {
for (i=0; i<number; i++)
dosomething;
}
for (i=0; i<5; i++)
x(2); // resets i to 2
// => never-ending loop
无限循环将使浏览器挂起,冻结界面,直到代码执行完毕。某些浏览器可能会因长时间运行的脚本而抛出错误,并通过超时实现。