Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Вопрос о циклических ссылках (JavaScript -> Dom -> JavaScipt) (https://javascript.ru/forum/events/7196-vopros-o-ciklicheskikh-ssylkakh-javascript-dom-javascipt.html)

BlueIce 20.01.2010 17:01

Вопрос о циклических ссылках (JavaScript -> Dom -> JavaScipt)
 
Привет!
На данный момент существует большая потребность разобраться в циклических ссылках. Поэтому знающих людей очень прошу помочь с нижеследующим примером. Есть такой javascript код и html.

<html>
<head>
<script type="text/javascript">   
function SuperDiv(id) {
        var privateDiv;
        this.Init() = function() { privateDiv = document.getElementById(id);}
        this.Hide() = function() { privateDiv.style.display = "none"; };
}

        var mySuperDiv = new SuperDiv("myDiv");    
</script>
</head>
<body onload="mySuperDiv.Init()">
<div id="myDiv" onclick="mySuperDiv.Hide()"></div>
</body>
</html>


Вопрос такой - образуется ли при таком подходе циклическая ссылка JavaScript -> Dom -> JavaScipt? (Особое внимание !!!
Вопрос не в том - правилен ли такой код или нет. И есть ли в нём смысл или нет! Это просто пример! :)

Насколько я понимаю - при создании замыкания функцией Hide - она сохраняет ссылку на объект переменных функции SuperDiv (для доступа к приватной переменной privateDiv). privateDiv держит ссылку на Dom элемент myDiv. А myDiv, в свою очередь, ссылается на функцию Hide через свойство onclick. Т е это циклическая ссылка и сборщик мусора IE не сможет её удалить? Или я где-то напутала?

Заранее спасибо за ответы.

vk65535 01.02.2010 19:18

Цитата:

Сообщение от BlueIce (Сообщение 41230)
А myDiv, в свою очередь, ссылается на функцию Hide через свойство onclick.

В том то и дело, что не ссылается. Функция работает в контексте элемента, а ссылка на функцию Hide извлекается из глобального контекста через переменную mySuperDiv. Вообще, текстовым обработчиком создать цикл при всем желании не получится. Вот если бы вы свойству onclick присвоили бы ссылку на функцию с замыканием, содержащим ссылку на этот dom-элемент - тогда другое дело.

В 8-м осле проблема циклических ссылок устранена.

BlueIce 01.02.2010 20:44

Спасибо за ответ, vk65535! Правда не всё до конца ясно
Вот если бы вы свойству onclick присвоили бы ссылку на функцию с замыканием, содержащим ссылку на этот dom-элемент - тогда другое дело.
Можно объяснить чуть подробнее этот момент? Ведь Hide - сама является замыканием и через приватную переменную var privateDiv ссылается на элемент myDiv.

В 8-м осле проблема циклических ссылок устранена.
По-моему проблема циклических ссылок устранена уже в 7. Но увы и ах приходится до сих пор поддерживать 6-й.

vk65535 02.02.2010 11:45

Вот пример, приводящий к ликам.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><body><button onclick="leak()">leak</button><script type="text/javascript">
var createBlock = function() {
	var e = document.createElement('div');
	e.onclick = function(){};
},
leak = function() {
	for (var i = 0; i < 10000; ++i) createBlock();
};
</script></body></html>


Проверяется очень просто.
dom-element -> onclick function -> var e -> dom-element

В 7-м, к сожалению, не устранена, а то б давно уже забил на эту проблему.

P.S. Здесь мелкомягкие балуются по этому поводу самокритикой.

x-yuri 02.02.2010 15:49

Цитата:

Сообщение от BlueIce
Насколько я понимаю - при создании замыкания функцией Hide

замыкание - это и есть функция

Цитата:

Сообщение от vk65535
В 7-м, к сожалению, не устранена

Цитата:

In Internet Explorer 7, these circular references are broken when users navigate away from the page that contains the leaks.
это проблема, если пользователь долго находится на странице и что-то периодически происходит, например, опрос почтового сервера

p.s. про патч и псевдоутечки

vk65535 02.02.2010 16:19

Цитата:

Сообщение от x-yuri (Сообщение 43237)
это проблема, если пользователь долго находится на странице и что-то периодически происходит

А какая разница, сколько находится пользователь на странице, если от перезагрузки страниц память не освобождается? ) Он может ходить по багнутым сайтам и осел скушает всю раму с той же охотой.

x-yuri 03.02.2010 21:19

Цитата:

Сообщение от vk65535
А какая разница, сколько находится пользователь на странице, если от перезагрузки страниц память не освобождается?

Цитата:

Сообщение от msdn
In Internet Explorer 7, these circular references are broken when users navigate away from the page that contains the leaks.

я торможу?

vk65535 04.02.2010 17:49

Я наверное не правильно понял слово broken (сломанные, глючные).
Если имеется в виду, что они, типа, рвутся и освобождаются - то это не так, попробуйте.
for (var i = 0, e; i < 1000000; ++i) (e = document.createElement('div')).e = e;

BlueIce 11.02.2010 19:56

Цитата:

Сообщение от vk65535 (Сообщение 43161)
В том то и дело, что не ссылается. Функция работает в контексте элемента, а ссылка на функцию Hide извлекается из глобального контекста через переменную mySuperDiv. Вообще, текстовым обработчиком создать цикл при всем желании не получится. Вот если бы вы свойству onclick присвоили бы ссылку на функцию с замыканием, содержащим ссылку на этот dom-элемент - тогда другое дело.

В 8-м осле проблема циклических ссылок устранена.

vk65535, и всё-таки мне кажется циклическая ссылка есть. Свой первый пример переписала в более простом виде. onclick присваивается функция, которая имеет через замыкание ссылку на сам объект DOM. Разве не так?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">  
<html>
<body>
<div id="myDiv"></div>
<script type="text/javascript">  

document.getElementById("myDiv").onclick = (function() {  
var e = document.getElementById("myDiv");   
return function hide() { e.style.display = "none"; };
})();  
</script></body></html>

vk65535 17.02.2010 21:51

В этом примере цикл действительно есть. В первом примере его нет.


Часовой пояс GMT +3, время: 12:47.