Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 21.02.2018, 19:15
BNB BNB вне форума
Интересующийся
Отправить личное сообщение для BNB Посмотреть профиль Найти все сообщения от BNB
 
Регистрация: 09.02.2018
Сообщений: 27

Задача про 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?
Ответить с цитированием
  #2 (permalink)  
Старый 21.02.2018, 19:27
Аватар для j0hnik
Профессор
Отправить личное сообщение для j0hnik Посмотреть профиль Найти все сообщения от j0hnik
 
Регистрация: 01.12.2016
Сообщений: 3,650

создает новую, убивая старую (пиф паф)
Ответить с цитированием
  #3 (permalink)  
Старый 21.02.2018, 19:31
BNB BNB вне форума
Интересующийся
Отправить личное сообщение для BNB Посмотреть профиль Найти все сообщения от BNB
 
Регистрация: 09.02.2018
Сообщений: 27

Что-то мне отладчик другое говорит
Ответить с цитированием
  #4 (permalink)  
Старый 21.02.2018, 19:33
Аватар для j0hnik
Профессор
Отправить личное сообщение для j0hnik Посмотреть профиль Найти все сообщения от j0hnik
 
Регистрация: 01.12.2016
Сообщений: 3,650

напишите в консоле img и посмотрите что в ней.
Ответить с цитированием
  #5 (permalink)  
Старый 21.02.2018, 20:10
BNB BNB вне форума
Интересующийся
Отправить личное сообщение для BNB Посмотреть профиль Найти все сообщения от BNB
 
Регистрация: 09.02.2018
Сообщений: 27

В цикле 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 сохранены в памяти, только теперь к ним нельзя обратиться из переменной.

Много букаф, но как мог описал ))
Ответить с цитированием
  #6 (permalink)  
Старый 21.02.2018, 20:26
Аватар для j0hnik
Профессор
Отправить личное сообщение для j0hnik Посмотреть профиль Найти все сообщения от j0hnik
 
Регистрация: 01.12.2016
Сообщений: 3,650

это то же самое что и
var a = 1;
var b = a;
a = undefined;
alert(b);
Ответить с цитированием
  #7 (permalink)  
Старый 21.02.2018, 20:32
BNB BNB вне форума
Интересующийся
Отправить личное сообщение для BNB Посмотреть профиль Найти все сообщения от BNB
 
Регистрация: 09.02.2018
Сообщений: 27

Ну тогда могу вопрос по другому задать) Почему DOM объекты img из трех итераций, после выхода из функции, которая их породила, еще остаются в памяти?
Ответить с цитированием
  #8 (permalink)  
Старый 21.02.2018, 20:41
Аватар для j0hnik
Профессор
Отправить личное сообщение для j0hnik Посмотреть профиль Найти все сообщения от j0hnik
 
Регистрация: 01.12.2016
Сообщений: 3,650

Потому что они нужны!

<!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 тут не причем
Ответить с цитированием
  #9 (permalink)  
Старый 21.02.2018, 20:52
BNB BNB вне форума
Интересующийся
Отправить личное сообщение для BNB Посмотреть профиль Найти все сообщения от BNB
 
Регистрация: 09.02.2018
Сообщений: 27

Хм.. ну тут то понятно, что с document.body.appendChild(div) мы сохраняем этот элемент в DOM и можем в div что угодно теперь присваивать, все равно прошлый элемент будет храниться в памяти. Но у меня же DOM объект не добавляется в сам документ, он лишь создается, потом в него заносятся данные, но он нигде не используется и более никак недоступен, поэтому он вроде должен удаляться из памяти. Но сейчас уже начинаю вспоминать, что читал про то, что переменная в которую записан объект DOM, но который не добавляли на саму страницу все равно будет просто так храниться в памяти. То есть даже если эту переменную перезапишут, то старый DOM объект будет "летать в облаках". Это так?))) Просто у меня это не состыковывается с тем, что в JS, если на объект больше никто не ссылается, то он удаляется из памяти как мусор (даже если этот объект сам ссылается на кого-то). В моем случае, что удерживает эти img от удаления их сборщиком мусора?
Ответить с цитированием
  #10 (permalink)  
Старый 22.02.2018, 12:56
Аватар для MallSerg
Профессор
Отправить личное сообщение для MallSerg Посмотреть профиль Найти все сообщения от MallSerg
 
Регистрация: 07.03.2011
Сообщений: 1,138

Сообщение от BNB Посмотреть сообщение
Ну тогда могу вопрос по другому задать) Почему DOM объекты img из трех итераций, после выхода из функции, которая их породила, еще остаются в памяти?
Потому что у каждого из них есть событие onload. которое и держит ссылки на эти объекты и не дает сборщику мусора их убрать.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Задача про графы LunarionXIV Общие вопросы Javascript 0 23.12.2014 13:39
Задача про onload img GennadiyK Общие вопросы Javascript 4 24.08.2014 11:39
Задача про Drag-n-Drop eirnvn Общие вопросы Javascript 5 01.07.2013 18:50
Задача про квадрат и треугольник dawsonsky Javascript под браузер 0 20.09.2012 15:34
Вопрос про вызов события onClick skyfish Общие вопросы Javascript 12 27.12.2008 19:12