>Форум Mozilla Россия http://forum.mozilla-russia.org/index.php >Разработка http://forum.mozilla-russia.org/viewforum.php?id=18 >JS closures: как избежать захвата ссылок на глобальные объекты? http://forum.mozilla-russia.org/viewtopic.php?id=51578 |
hydrolizer > 23-09-2011 15:02:07 |
.. в методе, передаваемом в другой контекст (с другими экземплярами тех же классов глобальных объектов)? Выделить код Код:var data={}; data.onOk=function(evt) { .... }; window.openDialog('chrome://someext/content/dialog.xul', '_blank' , 'chrome,dialog,modal,resizable,centerscreen',data); и в onLoad диалога Вроде бы всё хорошо, но если при объявлении data.onOk внутри тела метода использовать глобальные объекты (window, document, etc), то при этом самом объявлении происходит захват ссылок на эти глобальные объекты, и при отработке метода мы имеем дело со ссылками на объекты, принадлежащие области объявления метода, а не области вызова: Выделить код Код:var data={}; data.onOk=function(evt) { Services.console.logStringMessage(document.location); }; - при нажатии в вызванном диалоге на Ok мы в консоли получим не chrome://someext/content/dialog.xul, а chrome://someext/content/mainWindow.xul. - тоже без толку, захват по области видимости распространяется и на код внутри анонимного метода. |
hydrolizer > 23-09-2011 17:35:25 |
Разобрался. Если вспомнить, что привязка контекста определяет ссылку, получаемую от this, и если this ссылается на контекст окна, то мы можем получить ссылку на окно от this.window. Ну, а дальше всё становится достаточно просто: Выделить код Код:data.onOk=function(evt) { with (this) { Services.console.logStringMessage(document.location); } }; и при навешивании листенера Выделить код Код:document.documentElement.addEventListener("dialogaccept", data.onOk.bind(window), true); Тогда все отрабатывает именно так, как требовалось. |
Infocatcher > 24-09-2011 18:49:39 |
Еще не так давно появился метод Components.utils.createObjectIn(). |