Задача про img и события load/error
Есть задача: https://learn.javascript.ru/task/load-img-callback
В решении этой задачи есть строка с кодом: for (var i = 0; i < sources.length; i++) { var img = document.createElement('img'); img.onload = img.onerror = onLoad; img.src = sources[i]; } Как я понимаю, переменная, объявленная через var, будет одна на все итерации цикла for. Получается, что каждая новая итерация цикла будет перезаписывать переменную img новыми данными, но в данной ситуации интерпретатор для каждой итерации запоминает img как отдельную новую переменную и запоминает её в памяти отдельно. Получается, что каждая итерация не переприсваивает переменную img, её обработчики и src, а создает новую. На выходе мы имеем 3 разных img со своим атрибутом src и своими обработчиками. Почему так происходит? Это из-за атрибута src? |
создает новую, убивая старую (пиф паф)
|
Что-то мне отладчик другое говорит :no:
|
напишите в консоле img и посмотрите что в ней.
|
В цикле for решил также присвоить каждому img в атрибут id номер текущей итерации i, а в обработчик события load добавил вывод this.id в alert. Интерпретатор сначала прошелся по циклу: создал и перезаписывал переменную img с обработчиками и атрибутом src. Затем, после окончания цикла, поочередно загрузились картинки и начали срабатывать обработчики события load (ну уже тут можно понять, что интерпретатор сохранил по img из каждой итерации как отдельные DOM объекты). Каждый из трех обработчиков в alert выводил разный id (0, 1, 2). То есть получается, в цикле for интерпретатор запоминал переменную img отдельно и сохранял все её данные в памяти, даже с перезаписью на новые данные. После окончания цикла for, но не выходя из основной функции, img в консоли выдал последний img с id = 2, ну а после выхода из основной функции img is not defined. Пока думаю, что из-за src интерпретатор, во время перезаписи переменной с незагруженным src, сохраняет в памяти этот DOM объект и ждет, когда в нем загрузиться src, а вследствие этого сработают обработчики события load и уже потом интерпретатор выкидывает этот DOM объект из памяти, т.к. функция, где создали данный DOM объект уже закончила свою работу. Причем забавно то, что когда я вышел из функции preloadImages, ну где создали переменную img, но перед загрузкой картинок и срабатыванием обработчиков события load, переменная img уже не была доступна. То есть мы не можем ссылаться хотя-бы на последний img из последней итерации for (ну тут еще понятно из-за чего, основная функция закончила работу и более не нужна --> все лок. переменные удалены из памяти), но все img сохранены в памяти, только теперь к ним нельзя обратиться из переменной.
Много букаф, но как мог описал )) |
это то же самое что и
var a = 1; var b = a; a = undefined; alert(b); |
Ну тогда могу вопрос по другому задать) Почему DOM объекты img из трех итераций, после выхода из функции, которая их породила, еще остаются в памяти?
|
Потому что они нужны!
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script> for (var i = 0; i < 3; i++) { var div = document.createElement('div'); div.textContent = i; document.body.appendChild(div); } </script> </body> </html> тут DOM элементы будут еще дольше сохраняться. но перемеренная div тут не причем :no: |
Хм.. ну тут то понятно, что с document.body.appendChild(div) мы сохраняем этот элемент в DOM и можем в div что угодно теперь присваивать, все равно прошлый элемент будет храниться в памяти. Но у меня же DOM объект не добавляется в сам документ, он лишь создается, потом в него заносятся данные, но он нигде не используется и более никак недоступен, поэтому он вроде должен удаляться из памяти. Но сейчас уже начинаю вспоминать, что читал про то, что переменная в которую записан объект DOM, но который не добавляли на саму страницу все равно будет просто так храниться в памяти. То есть даже если эту переменную перезапишут, то старый DOM объект будет "летать в облаках". Это так?))) Просто у меня это не состыковывается с тем, что в JS, если на объект больше никто не ссылается, то он удаляется из памяти как мусор (даже если этот объект сам ссылается на кого-то). В моем случае, что удерживает эти img от удаления их сборщиком мусора?
|
Цитата:
|
Часовой пояс GMT +3, время: 03:37. |