0
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以下であり、この関数が3回以下実行された。この機能を削除すると、メモリリークは発生しません。

アップデート:

@GarethMcCaughanの提案に従って、alert(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回の実行しか表示されません。しかし、なぜ関数が繰り返し呼び出されるのでしょうか。

次に、コンソールがループの先頭にブレークポイントを報告していることを発見しました(コメントアウトしました)。これが、関数が呼び出しを続ける理由ですか?

4

2 に答える 2

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

于 2012-05-10T00:37:35.210 に答える
0

1つのバグを除けば、すべて問題ないようです。カウンター変数を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

無限ループによりブラウザがハングし、コードが実行されるまでインターフェイスがフリーズします。一部のブラウザは、タイムアウトを使用して実装された、実行時間が長すぎるスクリプトに対してエラーをスローする場合があります。

于 2012-05-10T00:41:27.407 に答える