Javascript 可以访问数组的元素,但不能在

Javascript 可以访问数组的元素,但不能在,javascript,jquery,ajax,arrays,Javascript,Jquery,Ajax,Arrays,我有一个URL数组和一个从外部提取的数据数组。URL和数据一一对应。我尝试这样做: for (var i = 0; i < children.length; i++) { urls.push(children[i].data.url); } for (var i = 0; i < children.length; i++) { $.ajax({ url: DATA_SOURCE, dataType: "jsonp",

我有一个URL数组和一个从外部提取的数据数组。URL和数据一一对应。我尝试这样做:

for (var i = 0; i < children.length; i++) {
    urls.push(children[i].data.url); 
}

for (var i = 0; i < children.length; i++) { 
    $.ajax({
         url: DATA_SOURCE,
         dataType: "jsonp",
         success: function (data2) {                           
             console.log(urls[0]);
             console.log(urls[i]);
         }
    });                        
}
for(变量i=0;i
第一个日志总是打印
url
数组的第一个元素。我可以将数字更改为任何其他有效的索引,它可以工作。但是,第二个日志始终打印未定义的
。我最初从第二个循环中获取URL,但我将其删除,以防它被证明是异步错误或其他什么<代码>URL
被初始化为
数组
,而不是
对象
。将第二个日志从success函数中取出(并进入for循环的主范围),使其按预期执行。我很乐意将其归因于ajax请求,不知怎么搞砸了它,但是为什么第一个日志会按预期执行呢


有什么想法吗?

$。ajax是异步的,这意味着当回调(成功)运行时,循环已经运行完毕,现在设置为childrence.length

访问URL[i]等于URL[children.length],因此未定义

解决这个问题的一个简单方法是为每个迭代创建范围

for (var i = 0; i < children.length; i++) { 
  (function( index ) {
    $.ajax({
       url: DATA_SOURCE,
       dataType: "jsonp",
       success: function (data2) {                           
         console.log(urls[ index ]);
        }
    }); 
  })( i );                       
}
for(var i=0;i
这是因为在最终调用成功函数时未定义i。您需要将i的当前值传递给正在生成的成功函数

for (var i = 0; i < children.length; i++) { 
    $.ajax({
         url: DATA_SOURCE,
         dataType: "jsonp",
         success: (function (count) {
             return(function(data2){console.log(urls[0]); console.log(urls[count]);});        
         })(i)
    });                        
}
for(var i=0;i

在这里,为每个迭代生成的成功函数都有细微的不同,因为它记录了不同的值。

+1对于Pantelis的回答,尽管只是一句有点迂腐的话:没有真正的必要将整个ajax调用封装在一个IIFE中,只有成功回调需要引用“当前”
i
的值,因此这将很好:

for (var i = 0; i < children.length; i++)
{
    $.ajax({
       url: DATA_SOURCE,
       dataType: "jsonp",
       success: ((function( index ) 
       {
           return function (data2)
           {
               console.log(urls[ index ]);
           };
       })(i)
    });
}
for(变量i=0;i
与其将URL用作另一个数组,为什么不能将子对象[i].data.url直接进入ajax
i
不是未定义的,当成功函数最终被调用时,它将等于
childrence.length
。因为成功回调引用了
i
,所以它不会超出范围,但在全局上下文中调用成功函数时,该值会一次又一次递增,不是吗?由于他使用的是(正确的)
var i=0
,我将无法在成功处理程序的上下文中访问。除非这些循环本身在全局上下文中运行,在这种情况下你是对的。不,这不是调用成功函数的上下文的问题:它被声明为对象文本的成员(
$.ajax({object:“literal”});
),因此该对象的方法引用的任何变量都不会被GC'ed,而不管调用函数对象/方法的上下文是什么,该函数对象/方法包含了我所讨论的一些示例:在另一个上下文中调用对象和闭包引用(关于
self
)@EliasVanOotegem看来我对javascript作用域的理解比我想象的要少。我现在正在看一些文章,感谢你指出这一点。这与我发布的有什么不同?@Asad:没有,但当我开始键入时,你的答案还没有更新。我发布这篇文章只是为了添加到Pantelis的答案中……唯一的区别是你声称
i
将是未定义的,但事实上,它不是很酷,这真的很好!我选择包装整个ajax调用的唯一原因是,在其余的回调(错误、进度)中可能也需要i。但是我更喜欢你的解决方案。