2017-02-24 12 views
1

私はこのコードがメモリリークの原因となるかもしれないと思う:Javascriptで関数をバインドするとメモリリークが発生する可能性がありますか?

function foo(arr, value){ 
    arr.push(value); 
    console.log(arr); 
} 
var bar = foo.bind(null, []); 
bar('first call');//output: ['first call'] 

//The next thing that confused me is happened, 
//'first call' has been hold in 'arr' after bar('first call') execute: 

bar('second call');//output: ['first call', 'second call']; 

GCは、最初の関数のパラメータの基準の集まりではありません、なぜ最初の関数が実行された後、私は不思議でしたか?

bar関数が実行されるたびに、仮パラメータarr[]に初期化する必要があると私は考えていました。

また、arr/[]以下の変数arr2の違いは何ですか?

var arr2 = []; 
function foo2(value){ 
    arr2.push(value); 
    console.log(arr2); 
} 
var bar2 = foo2.bind(null); 
bar2('first call 2'); 
bar2('second call 2'); 

ありがとうございます!

答えて

1

新しい配列の概念ではなく、作成し、新しい配列に初期化される特定のオブジェクトにバインドします。より正確には、JavaScriptの変数はオブジェクトのラベル/ポインタです。多くのラベルは同じオブジェクトを参照することができ、基礎となるオブジェクトが変更されると、各ラベルは「変化を見る」。例外は、プリミティブ型、およびそれ以外は不変(文字列、日付など)であり、インプレース修正が許可されていない型です。

次のコードは同等のようになります。

var baz = []; // or baz = new Array(); 
var bar = foo.bind(null, baz); // bind first argument to object pointed to by baz. 
bar('first call'); // operates on baz, making it ['first call'] 
bar('second call'); // operates on baz, making it ['first call', 'second call'] 
baz.push('x'); // ['first call', 'second call', 'x']; 

また、あなたの質問に応じて、これは標準的な動作です。 Python、Ruby、C#、Javaなど同様のセマンティクスを持つ他のすべてのプログラミング言語でもほぼ同じです。だから、foo2が永遠に生きているときだけメモリリークが起こりますが、あなたはそれがちょっとだけ生きていたかったのです。

+0

ありがとうございます!私は、 "ラベル/ポインタ"の意味を理解し始めたと思う...データアドレスの "参照"だけで、 "参照"がどこにポインタされているかを無視する...第1と第2のバー関数呼び出しは同じ最初のパラメータの "ポインタ"。再度、感謝します!!! –

関連する問題