问题描述
|
好的,每个人都解决了这个问题,但是我感觉还差一点就不知道该怎么做。
我想要一个设置一堆点击处理程序并为每个处理程序指定唯一参数的循环。我现在正在做这样的事情:
for (thisThing in things){
myDiv=document.createElement(\'img\');
myDiv.onclick=function(){
// do somehting!
// but don\'t do anything with \"thisThing\"
// because it\'s got the wrong value in it by the time you call it!
// but this function has to have the value of \"thisThing\" to work,dammit!
}
}
到处都可以找到解决方案,那就是关闭-哇!除了闭包中断即(对吗?)
在其他方面,我可以现场评估代码,在变量中烘烤,但这充其量看起来很丑陋,而且看起来可能会破坏某些东西
那这给我留下了什么?可以关闭吗?可以逃避吗?我是唯一一个在网络上动态创建按钮的人吗?!?任何帮助都感激不尽。很抱歉,这是基本的&实际上是经常回答的问题。
到目前为止,此页面提供了我所找到的最完整的答案,但是,它表明关闭是所有时间的解决方案。诅咒! http://www.howtocreate.co.uk/referencedvariables.html
解决方法
关闭不会破坏IE。
(function(someThing) {
myDiv.onclick=function(){
// Access it as \"someThing\"
}
})(thisThing);
jsFiddle。
问题在于分配给onclick
属性的函数会创建一个可以访问其父变量的闭包。
当您准备单击元素时,它的“ 3”已增加到终止循环的最终值(在您的情况下,最后一个属性被迭代),因为它访问外部变量而不是副本。
通过创建具有新的自调用函数的新闭包并传递thisThing
,其值将成为变量someThing
,并且仅位于内部函数内部。
这是缓解此已知问题的方法之一。
请注意,在IE6和7中存在内存泄漏。有关此问题的解决方案,请咨询RobG或Raynos的答案。
,问题是在循环中创建函数是BAD。一点点重构会使您的问题消失。
function createDiv(thing) {
var div = ...
div.onclick = ...
}
for (thisThing in things) {
createDiv(thisThing);
}
但是,这仍然会泄漏旧版本IE中的内存。
因为这个代码:
var div = ...;
div.onclick = function() { ...;
div
引用了该功能,而该功能引用了div
。这是一个循环参考。要解决此问题,您需要一个回调工厂。
function createDiv(thing) {
var div = ...
div.onclick = createCallback(thing);
}
function createCallback(thing) {
return function() {
...
};
}
这意味着您的onclick
回调没有引用div
元素。
, 我想要一个设置一个
一堆点击处理程序,并让每个
处理程序给出唯一的参数。我是
现在做这样的事情:
> for (thisThing in things){
> myDiv=document.createElement(\'img\');
>
> myDiv.onclick=function(){
> // do somehting!
> // but don\'t do anything with \"thisThing\"
> // because it\'s got the wrong value in it by the time you call it!
> // but this function has to have the value of \"thisThing\" to work,> dammit!
> } }
各地解决方案都被称为闭包
不,您根本不需要闭包。您正在尝试不关闭。
除了闭包中断即(对吗?)
错误。
IE和涉及DOM元素的循环引用存在问题,导致内存泄漏。该问题已在很大程度上得到解决,但是却被误解了。例如:
function addListener(element) {
var someVar = ...;
element.onclick = function() {
// this function has a closure to someVar
};
}
当调用addListener时,导致涉及到someVar闭包的特殊引用。有一些非常简单的修复程序。您想要做的是没有someVar的闭包,而是使用该值。可以通过多种方法来完成,但是最简单的方法是:
函数addListener(element){
var someVar = ...;
element.onclick =(function(differentVar){
警报(differentVar);
})(someVAr);
}
因此,现在someVar的值传递给了differentVar,这是内部函数的局部变量。当然,内部函数可能仍然具有someVar的闭包,但是使用立即调用的匿名函数会破坏differentVar
和someVar
之间的闭包。
作为其中之一,无论如何关闭都没有问题。但是,如果您要附加许多侦听器,并且它们都引用了someVar,则它们都具有相同的值。在这之间使用立即调用的匿名函数可以中断该链。
编辑
抱歉,最后一个示例不正确,我不好。
function addListener(element) {
var someVar = ...;
element.onclick = (function(differentVar) {
return function() {
alert(differentVar);
};
})(someVAr);
}
,关闭不会破坏IE。
for (thisThing in things){
if(!things.hasOwnProperty(thisThing)) continue;
var myDiv = new document.createElement(\'img\');
myDiv.onclick = (function(thing){
// Instance specific vars and other thigns
return function() {
// More stuff
}
})(thisThing);
}