Да, s.onload = null
полезно и будет собирать мусор!
С 2019 года явный или программный запуск сбора мусора в JavaScript невозможен.Это означает, что он собирает, когда захочет.
Хотя есть случаи , когда установка на null
может сделать GC раньше (но не инициировать это).
С 2012 года все современные браузеры поставляют сборщик мусора .
Он работает по принципу достижимости :
Каждый объект, недоступный из глобального контекста, удаляется
Периодически mark-and-sweep обнаруживает и удаляет объект, когда каждая переменная, в которой он находится, является возвращено, переназначено или установлено на ноль .Кроме того, в настоящее время нет необходимости рекурсивно устанавливать значение NULL для содержимого, которое не доступно ни для одной переменной - оно все равно собирается mark-and-sweep .
А теперьрассматриваемый код ...
В первой строке мы видим, что s
и дочерний элемент document.head
указывают на то же document.createElement('script')
.Когда функция возвращается и замыкание удаляется из стека вызовов, ее объявленная переменная s
также удаляется.Значение, на которое ссылается s
, не является сборщиком мусора, потому что оно все еще доступно через document
.
Итак. Нет необходимости в s = null
, так как указатель очищается в любом случае, когда переменная удаляется, но естьstill является ссылкой на свойство сценариев onload
, поскольку <script onload>
является потомком document.head
в DOM, достижимом из window
!
Содержимое callback
может быть доступно, но здесь не может быть и речи.
Что если браузер достаточно умен, чтобы установить s.onload = null
внутри?Мы опробуем его, сначала закомментировав его в первом фрагменте, и раскомментировав его во втором фрагменте ...
function fetch(src, callback, fail) {
let s = document.head.appendChild(document.createElement('script'));
s.type = "text/javascript";
s.src = src;
s.onload = function() {
callback()
//s.onload = null; //useful?
}
s.onerror = fail
}
fetch("https://stackoverflow.com",
() => {console.log("Execute onload");},
() => {console.log("File not found");})
setTimeout(() => {
console.log(document.head.lastChild.onload)
},1000)
Найденный файл выполняется с ошибкой, поскольку он не является Javascript.
onload
выполняется, но не удаляется.Код отображается в журнале!
Это подтверждает, что следует использовать строку с s.onload = null
, например:
function fetch(src, callback, fail) {
let s = document.head.appendChild(document.createElement('script'));
s.type = "text/javascript";
s.src = src;
s.onload = function() {
callback()
s.onload = null; //useful!
}
s.onerror = fail
}
fetch("https://stackoverflow.com",
() => {console.log("Execute onload");},
() => {console.log("File not found");})
setTimeout(() => {
console.log(document.head.lastChild.onload)
},1000)