Когда объекты JavaScript уничтожаются?

В С++ я могу определить конструктор и деструктор явно, а затем cout < "C или D вызывается" из функции конструктора/деструктора, чтобы точно знать, где.

Однако в 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();
    }
};

Ответ 1

Объекты JS не имеют деструкторов как таковые.

Объекты JavaScript (и примитивы) - это сбор мусора, когда они становятся недоступными, что означает отсутствие ссылки на них в текущем контексте выполнения. Время выполнения JavaScript для этого постоянно отслеживается. Поэтому, если вы не используете ключевое слово delete, чтобы удалить что-то, то его разрушение под капотом. Некоторые браузеры плохо обнаруживают ссылки, оставшиеся в области закрытия (я смотрю на вас, Редмонд), и поэтому вы часто видите, что объекты, которые были установлены в нуль в конце функций, - чтобы убедиться, что память освобождена в IE.

Ответ 2

Это представление о том, что уничтожение объекта сводится к сборке мусора для памяти, поражает меня как опасное введение в заблуждение, так как проблема не сводится к освобождению памяти.

Деструкторы несут ответственность за освобождение других ресурсов, таких как дескрипторы файлов или прослушиватели событий, которые автоматически не обрабатываются сбором мусора. В таких случаях деструкторы абсолютно необходимы для разматывания состояния до освобождения памяти или утечки ресурсов.

В таких случаях проблема заключается в том, что деструкторы не являются первоклассным понятием, нужно ли их явно называть или их можно назвать неявно после того, как объект становится недоступным.

Лучший способ справиться с этим - правильно документировать ваши модули, если им нужны деструкторы, которые будут использоваться, и подчеркивать сценарии утечки ресурсов, которые не могут использоваться таким образом.

Ответ 3

В ECMAscript отсутствует управление динамической памятью. Сборщик мусора позаботится о том, что требует памяти в вашем script. Поэтому на самом деле вопрос должен быть более похож,

"Как знает сборщик мусора, когда он может освобождать память для объектов"

Проще говоря, большинство GC смотрят, есть ли какие-либо активные ссылки. Это может быть связано с родительским контекстным объектом, цепочками прототипов или любым прямым доступом к данному объекту. В вашем конкретном случае в любое время setTimeout выполняется выполнение, он вызывает next(), который закрывается в родительском контексте .fade(), а функция .face(), в свою очередь, закрывает функцию Effects (контекст).

Это означает, что до тех пор, пока есть вызовы setTimeout, вся целая конструкция хранится в памяти.

Вы можете иногда помогать старым реализациям GC, используя null переменные переменные/ссылки на них, которые могут собирать некоторые вещи раньше или вообще, но современные реализации довольно умен в этом отношении. На самом деле вам не нужно заботиться о таких вещах, как "Живое время объекта/ссылки".

Ответ 4

Существует экспериментальная функция Firefox и Chrome window.requestIdleCallback(), которая вызывает браузер в режиме ожидания. Это может быть использовано для имитации деструктора экземпляра класса.

Почти такой же эффект можно получить из следующего кода:

setTimeout(function()
    {
    // Simulate destructor here
    },0);

Это устанавливает автоматически отклоненное время ожидания, которое завершается, когда завершается текущий скрипт JavaScript.