`new` без` delete` для той же переменной в Javascript - PullRequest
12 голосов
/ 02 февраля 2011

Можно ли это сделать?:

function mygetTime()
{
    var d = new Date();
    return(d.getTime());
}

function wasteSomeMemory()
{
    var temp;
    for(var count = 0; count < 1000000; count += 1)
    {
        temp = mygetTime();
    }
}

Будет ли вызов wasteSomeMemory() вызывать утечку памяти?

Как насчет этого:

function wasteSomeMemory2()
{
    var temp;
    for(var count = 0; count < 1000000; count += 1)
    {
        temp = new Date();
    }
}

Будетвызов wasteSomeMemory2() вызывает утечку памяти?Должен ли я использовать delete temp; в конце цикла for?

function wasteSomeMemory2()
{
    var temp;
    for(var count = 0; count < 1000000; count += 1)
    {
        temp = new Date();
        delete temp;
    }
}

Ответы [ 2 ]

31 голосов
/ 02 февраля 2011

new и delete не имеют ничего общего друг с другом в JavaScript (несмотря на их запутанное сходство с совершенно разными конструкциями в других языках).Не беспокойтесь о создании объектов (new) без явной очистки, это задача сборщика мусора.

new - для создания объектов с помощью функций конструктора.delete, с другой стороны, для удаления свойств из объектов.Он не имеет ничего общего с удалением объекта из памяти, кроме как побочный эффект (например, если единственная выдающаяся ссылка на этот объект была из свойства, которое вы удалили).

Пример правильного использования delete:

var obj = {};
obj.foo = "bar"; // Now `obj` has a property called `foo`
delete obj.foo;  // Now it doesn't

Ваша функция getmyTime в порядке.Объект Date может быть возвращен сразу после возврата функции (независимо от того, является ли исправленным , полностью зависит от реализации).Это не вызывает утечку памяти, кроме как с ошибочной реализацией.

Ваш wasteSomeMemory2 аналогично не вызывает утечку памяти, и на самом деле вы не можете вызвать delete temp;- вы можете удалять только свойства, а не переменные.


* В 1029 * случаях приходится помогать сборщику мусора, но обычно это не так (по моему опыту)делать со свойствами объекта и не включать delete.Они действительно появляются только при создании экземпляров функций (что довольно часто, если вы настраиваете обработчики событий или функции таймера и т. Д.).Например, рассмотрим:

function foo() {
    var listOfThings = /* ...get a list of things... */;

    // ...do something with `listOfThings`...

    setInterval(function() {
       // ...do something that *doesn't* need `listOfThings`...
    }, 1000);
}

Поскольку ваша анонимная функция, назначенная вами для таймера с помощью setInterval, выдержит вызов функции, она сохраняет прямую ссылку на все, что находилось в области действия во время этой функции.вызов (использует ли он это или нет).Это сохраняет список вещей, на которые указывает listOfThings, в памяти.Если функция таймера не нуждается в этом списке, это проблема.Вы можете освободить список, на который указывает listOfThings, если знаете, что функция ему не нужна, назначив undefined или null или что-то еще listOfThings, когда вы закончите с этим:

function foo() {

    var listOfThings = /* ...get a list of things... */;

    // ...do something with `listOfThings`...

    listOfThings = undefined; // Done with it           <== The new bit

    setInterval(function() {
       // ...do something that *doesn't* need `listOfThings`...
    }, 1000);
}

То же самое верно для функций-обработчиков событий и т. Д. Каждый раз, когда вы создаете функцию, она «закрывает» (сохраняет прямую ссылку) все, что находится в области видимости, в которой она была определена.Поэтому, если вам не нужны эти вещи, вы можете убедиться, что они не хранятся в памяти, очистив ссылки на них.(Подробнее: Затворы не сложны )

4 голосов
/ 02 февраля 2011

Короткий ответ - нет.

Длинный ответ: мы надеемся, что бог-сборщик мусора поднимет это.

...