2017-09-08 11 views
0

私はJSのメモリ管理についてもっと知りたいと思っています。私はクロージャについていくつかの質問があります。Javascript:名前付きクロージャとメモリ管理

ケース:

// Suppose that object var is capable to emit events 
var object = new EventEmitter(); 

object.addEventListener('custom-event', function callback(event) { 
    object.removeEventListener('custom-event', callback); 
    object = null; 

    //Do some heavy computation like opening a specific view or somehthing similar 
    var heavy_window = new HeavyWindow(); 
    heavy_window.open(); 
}); 

ケース:

// Suppose that object var is capable to emit events 
var object = new EventEmitter(); 

object.addEventListener('custom-event', callback = function(event) { 
    object.removeEventListener('custom-event', callback); 
    object = null; 

    //Do some heavy computation like opening a specific view or somehthing similar 
}); 

私の質問

は、次のとおりです。

  • ケース1:

    • objectは、heavy_windowが無効になるまでメモリに残りますと考えるのは正しいですか?
    • クロージャ内でobject varをヌルするとgcに役立つことがありますか?
  • ケース2:メモリリークが発生する可能性があります...addEventListener(callback = function() {})代わり...addEventListener(function callback() {})のこのような方法で閉鎖を命名

    • callback = function() {}を宣言すると、グローバルな隠れ変数が発生しますか?

注、私はjQueryのでは例が必要か、他のフレームワークを使用しないでください。私はJavaScriptのバニラでもっと知りたいと思っています。

ありがとうございます。

+0

ケース1について、「オブジェクト」は「heavy_window」とは何が関係していると思いますか? – Bergi

+0

@Bergi 'heavy_window'は' object'に付けられたリスナの内部に作られています。 'heavy_window'が存在するまで、' object'はメモリに残ります。私は正しい? – Andrea

+0

いいえ、リスナー関数が 'object'に付加されている可能性がありますが、呼び出し中に作成されたものはそうではありません。関数が返ってくると範囲外になり、何も参照を保持しません。あなたがどこかに明示的にそれらを格納していないか、関数から関数を返すことができないので、呼び出し元が何かを行う可能性があります。 – Bergi

答えて

0

ガベージコレクションの詳細がES仕様で指定されているとは限りません。しかし、ほとんどのインタプリタでは、オブジェクトへの参照が存在しないか、アクセスできない、または後でスケジュールされると、オブジェクトは通常ガベージコレクションされます。ケース1では

heavy_windowは元new EventEmitterevent多くの場合、イベントターゲットへの参照を持っている)あなたはHeavyWindowにイベントオブジェクトを渡す場合にアクセスできる場合がありますので、ごnew EventEmitter()は、ガベージコレクションへのすべての参照までではないかもしれませんあなたheavy_windowはなくなりました。そうでない場合、あなたのnew EventEmitterは将来、ある時点でガベージコレクションされます。

ケース2の場合、コールバック関数には、作成した実際のnew EventEmitterオブジェクトへの参照がないため、グローバル変数callbackにコールバック関数を代入しても何も変更されません。

実際には、ブラウザのガベージコレクタはかなり複雑なので、状況は多少異なる場合があります。通訳者がいつごみを収集するかは本当に決まっていますが、最終的には、オブジェクトへのすべての参照がなくなったときにのみ行うようにしています。

通常、メモリ管理はJavaScriptではありませんが、JavaScriptはほとんどの場合それについて考える必要はありません。メモリリークがあり、ブラウザが提供する開発ツールを使用してメモリリークを検出できる場合は、そのことがわかります。