jQuery AJAX函数无法看到我的变量

时间:2010-10-20 15:48:46

标签: javascript jquery ajax

我有以下代码,我已简化,$currEl被记录并正确显示,但在$ .ajax调用中它记录为null

我错过了什么吗?

for(var i=0, j = atgSlots.length; i < j; i++) {
 var currSlot = atgSlots[i].split('|'),
   $currEl = currSlot[0].length ? $('[data-atg-url=' + currSlot[0] + ']') : null,
   wcmLocation = currSlot[2] || null;

 if ($currEl !== null && wcmLocation !== null) {
  console.log($currEl);
  $.ajax({
   url: wcmLocation,
   success: function(html) { console.log($currEl); updateSlots.setContent($currEl, html); },
   error: updateSlots.checkDefault
  }); // $.ajax
 }
} // for : atgSlots

2 个答案:

答案 0 :(得分:3)

问题是你的ajax成功函数有一个实时引用 $currEl变量,而不是 copy ,就像创建函数时一样。因此,所有这些成功处理程序都引用相同的变量,因此引用相同的值 - 循环中分配给$currEl的最后一个值。这是一个相同效果的简单例子:

var a;
a = "before";
setTimeout(function() {
    alert(a);
}, 10);
a = "after";

警告“之后”而不是“之前”,因为在10ms之后调用的函数使用当前值aSee it in action

您可以通过使用中间函数为每个函数提供自己的变量来解决此问题。这是一个极简主义的变化:

for(var i=0, j = atgSlots.length; i < j; i++) {
 var currSlot = atgSlots[i].split('|'),
   $currEl = currSlot[0].length ? $('[data-atg-url=' + currSlot[0] + ']') : null,
   wcmLocation = currSlot[2] || null;

 if ($currEl !== null && wcmLocation !== null) {
  console.log($currEl);
  $.ajax({
   url: wcmLocation,
   // ==== Change starts here
   success: (function($thisEl) {
     return function(html) { console.log($thisEl); updateSlots.setContent($thisEl, html); };
   })($currEl),
   // ==== Change ends here
   error: updateSlots.checkDefault
  }); // $.ajax
 }
} // for : atgSlots

这样做是在每个循环上创建并调用工厂函数,将函数传递给$currEl的当前值。然后该函数返回应该用作成功处理程序的函数。成功处理程序使用外部上下文中的其他信息(html,我假设它们应该对所有这些信息都是通用的),但使用$thisEl(函数参数)而不是$currEl

以这种方式执行它实际上略微效率低,因为我们创建了新工厂函数的多个相同副本。一个不太简约 - 也许更清晰 - 的版本看起来像这样:

for(var i=0, j = atgSlots.length; i < j; i++) {
 var currSlot = atgSlots[i].split('|'),
   $currEl = currSlot[0].length ? $('[data-atg-url=' + currSlot[0] + ']') : null,
   wcmLocation = currSlot[2] || null;

 if ($currEl !== null && wcmLocation !== null) {
  console.log($currEl);
  $.ajax({
   url: wcmLocation,
   success: buildSuccessHandler($currEl),
   error: updateSlots.checkDefault
  }); // $.ajax
 }
} // for : atgSlots

function buildSuccessHandler($thisEl) {
    return function(html) {
        console.log($thisEl);
        updateSlots.setContent($thisEl, html);
    };
}

(我假设所有这些代码都包含在某个函数中。)

有关闭包的更多信息以及此博文中的实时参考资料:"Closures are not complicated"

答案 1 :(得分:0)

问题可能是当调用AJAX回调时,$ currEl将被设置为不同的值,或者为null,因为它将在调用回调时获取$ currEl的值,而不是在声明AJAX函数时