27

C++ では、コンストラクタとデストラクタを明示的に定義してから、正確な場所を知るために、コンストラクタ/デストラクタ関数内で << "C or D Called" を使用できます。

ただし、JavaScript では、オブジェクトがいつ破棄されたかをどのように知ることができますか。以下の例は、私が関係するケースです。

タイムアウト時に内部関数を呼び出していますが、タイマーが実行されている限りオブジェクトが生き続け、次の呼び出しを待っているかどうか疑問に思っています。

ユーザー クリック コール コントロール

// Calls  Control

コントロール コール メッセージ

var message_object = new Message( response_element );

メッセージ通話の効果

new Effects().fade( this.element, 'down', 4000 );
message_object.display( 'empty' );

効果

/**
 *Effects - build out as needed
 *  element - holds the element to fade
 *  direction - determines which way to fade the element
 *  max_time - length of the fade
 */

var Effects = function(  ) 
{
    this.fade = function( element, direction, max_time ) 
    {
        element.elapsed = 0;
        clearTimeout( element.timeout_id );
        function next() 
        {
            element.elapsed += 10;
            if ( direction === 'up' )
            {
                element.style.opacity = element.elapsed / max_time;
            }
            else if ( direction === 'down' )
            {
                element.style.opacity = ( max_time - element.elapsed ) / max_time;
            }
            if ( element.elapsed <= max_time ) 
            {
                element.timeout_id = setTimeout( next, 10 );
            }
        }
        next();
    }
};
4

5 に答える 5

27

編集 2020: @BuffyG からのこの回答は、以下の古い回答よりもはるかに正確で便利です。オブジェクトの破壊は単なるメモリ リークにとどまりません。最新の JavaScript には、私が言及したパターンはありません。

JS オブジェクト自体にはデストラクタがありません。

JavaScript オブジェクト (およびプリミティブ) は、アクセス不能になったとき、つまり現在の実行コンテキストでそれらへの参照が不可能になったときにガベージ コレクションされます。JavaScript ランタイムは、これを継続的に監視する必要があります。したがって、delete何かを削除するためにキーワードを使用しない限り、その破壊は一種のボンネットの下にあります. 一部のブラウザーは、クロージャー スコープに残っている参照を検出するのが苦手です (レドモンドさん、私はあなたを見ています)。そのため、IE でメモリが解放されていることを確認するために、関数の最後でオブジェクトが null に設定されていることがよくあります。

于 2012-04-11T19:39:54.517 に答える
4

ECMAscript には動的メモリ管理はまったくありません。ガベージ コレクターは、スクリプトでメモリを必要とするあらゆる処理を行います。したがって、実際には、質問はもっと似ているはずです。

「ガベージ コレクターは、オブジェクトのメモリを解放できるタイミングをどのように知るのですか」

簡単に言えば、アクティブな参照がある場合のほとんどの GC の外観です。これは、親コンテキスト オブジェクト、プロトタイプ チェーン、または特定のオブジェクトへの直接アクセスが原因である可能性があります。あなたの特定のインスタンスでは、いつでも実行され、親コンテキストを閉じるsetTimeout呼び出しが行われ、関数は関数へのクロージャーを保持します( context )。next().fade().face()Effects

つまり、 への呼び出しがある限りsetTimeout、その構成全体がメモリに保持されます。

変数を ing することで、古い GC 実装を少しだけ助けることができます。/nullそれへの参照は、いくつかのものを以前に収集することも、まったく収集することもできますが、最新の実装は、このことについてかなりスマートです。実際には、「オブジェクト/参照のライブ時間」などを気にする必要はありません。

于 2012-04-11T19:40:48.667 に答える