可能重复:
Javascript closure inside loops - simple practical example
我在手机应用程序中遇到关闭问题。我有一个JSON对象,其中包含有关如何创建表单的说明。这大致是代码:
for (var i in this.form.elements) {
var element = this.form.elements[i];
switch (element.type) {
// other cases
case 5:
var addThumb, photoInput;
addThumb = function (domId) {
return function (imgData) {
console.log('id: ' + domId);
$(domId).attr({src: 'data:image/jpeg;base64,' + imgData});
}
}('#thumb-'+element.id);
photoInput = $('<input>')
.attr({type: 'button', value: element.name, name: element.type, id: element.id, 'class': 'photobutton'})
.click(function (filename, cb) {
return function() {
console.log('taking photo and saving to ' + filename)
takePhoto(filename,addThumb)
}
}('photo-'+element.id, addThumb)
);
photoThumb = $('<img>').attr({id: 'thumb-'+element.id, 'class': 'thumbnail', src: 'img/target.png'});
$('#content').append(photoInput, photoThumb);
break;
}
}
单击照片按钮可打开相机拍照,并将其保存到磁盘。保存后,使用base64照片数据调用addThumb以替换缩略图图像。我的测试表单的每个输出是:
taking photo and saving to file photo-686
id: '#thumb-690
获取照片的闭包有效,但当addThumb被调用为回调时,domId
显示经过for循环的最后一个element.id。给定两个缩略图,无论按下哪个按钮,第二个都会被替换。它发生在iPhone和Android上,所以我写它的方式一定有问题。我做错了什么?
答案 0 :(得分:2)
takePhoto(filename, addThumb)
您需要在此处的闭包内传递cb
变量,而不是未受“保护”的addThumb
。好像忘记在“保护”它时更改变量名称。
答案 1 :(得分:1)
问题是addThumb
变量本身不受闭包的保护。它在创建时包含element.i
d的值,但在下一次出现的循环中被替换。所以你总是调用最后创建的addThumb
函数。
您可以构建一个封闭element
的封闭,而不是尝试单独保护每个变量:
for (var i in this.form.elements) {
var element = this.form.elements[i];
(function(element){
switch (element.type) {
...
})(element);
}