`new` без` delete` на той же переменной в Javascript

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

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;
    }
}

Ответ 1

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; — вы можете удалять только свойства, а не vars.


Иногда вам приходится помогать сборщику мусора, но обычно не имеют (по моему опыту) свойств объекта и поэтому не включают 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);
}

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

Ответ 2

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

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