Включает ли ES6 const сбор мусора?

В новом названии Кайла Симпсона вы не знаете JS: ES6 и выше, я нахожу следующий фрагмент:

ПРЕДУПРЕЖДЕНИЕ Назначение объекта или массива в качестве константы означает, что значение не сможет быть собрано в мусор, пока эти константы лексической области не исчезнут, так как ссылка на значение никогда не может быть отменена. Это может быть желательно, но будьте осторожны, если это не ваше намерение!

(Отрывок из: Симпсон, Кайл. "Вы не знаете JS: ES6 и Beyond". O'Reilly Media, Inc., 2015-06-02. iBooks. Этот материал может быть защищен авторским правом.)

Насколько я вижу, он не расширяется, и 10 минут на Google ничего не показывают. Это правда, и если да, то что означает "ссылка на ценность никогда не может быть отменена"? У меня есть привычка объявлять переменные, которые не будут изменены как const, является ли это плохой привычкой в ​​реальных конкретных условиях работы/памяти?

Ответ 1

Нет, никаких последствий для производительности нет. Это примечание относится к практике оказания помощи сборщику мусора (который достаточно редко необходим) путем "снятия" переменной:

{
    let x = makeHeavyObject();
    window.onclick = function() {
        // this *might* close over `x` even when it doesn't need it
    };
    x = null; // so we better clear it
}

Это, очевидно, не возможно сделать, если вы объявили x как const.

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

Ответ 2

ПРЕДУПРЕЖДЕНИЕ Назначение объекта или массива в качестве константы означает, что значение не сможет быть собранным мусором до тех пор, пока эти константы не будут лексическими область действия исчезает, так как ссылка на значение никогда не может быть отменена. Это может быть желательно, но будьте осторожны, если это не ваше намерение!

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

При объявлении переменной const вы не можете назначить переменной что-то вроде "" или null, чтобы очистить ее содержимое. Это действительно единственное отличие в управлении памятью. Автоматическая сборка мусора вообще не зависит от того, объявлена ​​ли она const или нет.

Итак, если вы хотите изменить содержимое переменной в будущем по какой-либо причине (в том числе вручную удалить ссылку на что-то, чтобы раньше можно было собрать мусор), тогда не используйте const. Это то же самое, что и любая другая причина использования или отсутствия использования const. Если вы хотите изменить то, что содержит переменная в любое время в будущем (по какой-либо причине), не используйте const. Это должно быть совершенно очевидно для всех, кто понимает, что означает const.

Вызов сборки мусора в качестве особого случая, когда не использовать const, просто кажется мне глупым. Если вы хотите очистить содержимое переменной, то это означает, что вы хотите изменить переменную so duh, не используйте const. Да, ручное включение сбора мусора в большой структуре данных, которая может быть захвачена в длительной области/закрытии, является одной из причин, по которой вам может понадобиться изменить эту переменную в будущем. Но это всего лишь одна из миллионов причин. Итак, я повторяю еще раз. Если вы когда-либо захотите изменить содержимое переменной по какой-либо причине в будущем, не объявляйте ее как const.

Сам сборщик мусора не обрабатывает переменную const или содержимое, которое она указывает на любую, отличную от переменной var или let. Когда он выходит из сферы действия и больше недоступен, его содержимое будет иметь право на сбор мусора.

const имеет ряд преимуществ. Это позволяет разработчику заявить о каком-то намерении, что содержимое этой переменной указывает на то, что код не может быть изменен, и может позволить среде выполнения сделать некоторые оптимизации, поскольку он знает, что содержимое переменной не может быть изменено. И, это предотвращает из-за того, что изгоев или случайный код никогда не меняет содержимое этой переменной. Все это хорошо, когда используется в соответствующем случае. В общем, вы ДОЛЖНЫ использовать const как можно больше.

Ответ 3

Как работают сборщики мусора (GC), когда что-то ссылается ничем ( "невозможно достичь" ), GC может с уверенностью сказать, что что-то больше не используется и вернуть память, используемую этим чем-то.

Возможность заменить значение переменной позволяет удалить ссылку на значение. Однако, в отличие от var, const нельзя переназначить значение. Таким образом, нельзя удалить эту константу из ссылки на значение.

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

Ответ 4

Эта заметка в моей книге касалась таких случаев, когда вы хотели бы вручную сделать значение GC'able раньше, чем конец его родительской области:

var cool = (function(){
   var someCoolNumbers = [2,4,6,8,....1E7]; // a big array

   function printCoolNumber(idx) {
      console.log( someCoolNumbers[idx] );
   }

   function allDone() {
      someCoolNumbers = null;
   }

   return {
      printCoolNumber: printCoolNumber,
      allDone: allDone
   };
})();

cool.printCoolNumber( 10 ); // 22
cool.allDone();

Цель функции allDone() в этом глупом примере - указать, что есть моменты, когда вы можете решить, что вы сделали с большой структурой данных (массив, объект), хотя окружающая область/поведение может жить на (через закрытие) на неопределенное время в приложении. Чтобы позволить GC собирать этот массив и восстанавливать его память, вы отключите ссылку с помощью someCoolNumbers = null.

Если вы объявили const someCoolNumbers = [...];, тогда вы не сможете этого сделать, чтобы память оставалась используемой до тех пор, пока родительская область (через закрытие, что методы в cool) не исчезнет, ​​когда cool не будет отменена или сам GCd.

Update

Чтобы было совершенно ясно, потому что здесь есть много путаницы/аргумента в некоторых потоках комментариев, это моя точка:

const абсолютно положительно, несомненно, оказывает влияние на GC - в частности, способность значения, чтобы быть GCD вручную на более раннее время. Если значение ссылается через объявление const, вы не можете отключить эту ссылку, а это означает, что вы не можете получить значение GCd ранее. Значение может быть только GCd, когда область срывается.

Если вы хотите, чтобы вручную можно было присвоить значение, имеющее право на GC ранее, в то время как родительская область все еще выживает, вы должны будете убрать свою ссылку на это значение, и вы не можете этого сделать, если вы использовали const.

Некоторые, похоже, полагали, что мое требование было const предотвращает GC. Это никогда не было моим утверждением. Только это предотвратило ранее ручной GC.