for循环不工作打印不正确的值。需要指数

时间:2015-01-19 01:42:58

标签: javascript for-loop

我无法理解for循环无法正常工作的原因

for (x = 0; x < 10; x++) { 
url= 'http://capc-pace.phac-aspc.gc.ca/details-eng.php?project='+x;
urllib.request(url, function (err, data, res) {
    if (err || res.statusCode !=200) {
    }
    else{
    console.log(x);
    }
});
}

我总是把这作为我的回答

s452:scripts 04101frt$ node javascriptparser.js 
10
10
10
10
10

我希望能够获得所有不具有重定向功能的网页(即他们的网址中的数字)

数字的数量变得很好(在这种情况下为5)但我希望得到它们的正确值。

2 个答案:

答案 0 :(得分:1)

所以,你正在使用闭包,不是吗?

Closure是从匿名函数内的父作用域捕获变量x的东西。 x将始终引用该变量指定的最后一个值,即使&#34;创建的函数&#34;变量已经很久了。

您需要在每个步骤中传递变量值的副本。像这样:

for (x = 0; x < 10; x++) { 
  url= 'http://capc-pace.phac-aspc.gc.ca/details-eng.php?project='+x;
  (function (x) {
    urllib.request(url, function (err, data, res) {
      if (err || res.statusCode !=200) {
      }
      else{
        console.log(x);
      }
    }
  })(x);
}

看看我们做了什么?新的立即调用的函数表达式(IIFE)接收其参数的值。这样我们就可以有效地创建10个循环计数器副本。 console.log(x)引用此参数,而不是外部循环计数器。

答案 1 :(得分:1)

你在这里遇到的是由javascript的功能级别范围引起的。花点时间阅读一下 - 它很好地解释了发生了什么 http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html

这是一个更可视化问题的小提琴 -

http://jsfiddle.net/tm604oLu/

var url;
//wrong: because of being all on the same scope the value of x is 9 at the time it's evaluated
for (x = 0; x < 10; x++) {
    url = 'http://capc-pace.phac-aspc.gc.ca/details-eng.php?project=' + x;
    setTimeout(function () {
        console.log(url);
    }, 1);
}

//correct behavior: by passing the url as the parameter to a function you are creating a new 'scope' and the value does not get overwritten
for (x = 0; x < 10; x++) {
    url = 'http://capc-pace.phac-aspc.gc.ca/details-eng.php?project=' + x;
    (function (ownScope) { 
        setTimeout(function () {
            console.log(ownScope);
        }, 1);
    }(url));
}

通过创建IFFE(立即调用的函数表达式),您可以创建一个新范围 - 这有助于保留计数器的预期值。