在CoffeeScript中迭代对象时的范围

时间:2013-03-31 02:48:24

标签: javascript coffeescript

在迭代coffeescirpt中的对象时,我遇到了一个范围问题。我在循环数组时遇到了类似的问题,但是能够使用forEach解决这个问题,这为每个循环提供了一个新的范围。现在我有一个类似的问题,除了一个数组,这次我使用一个对象/字典。问题是当循环遍历对象时,最后console.log总是为所有人返回对象中最后一个人的数据。我认为这是一个范围问题,但我不确定如何解决它。

for name, data of people
    console.log name
    lookup name, (err, other_data) ->
        console.log data  # this always returns the data for the last person

2 个答案:

答案 0 :(得分:4)

使用do block

for name, data of people
    console.log name
    do (data) ->
        lookup name, (err, other_data) ->
            console.log data

答案 1 :(得分:1)

Ionut的回答是正确的,我赞成它。

为了进一步解释,您遇到的问题是因为您传递的回调函数是以某种方式异步运行的。所以你的循环一直运行,最后的数据被设置为它的最终值。然后异步回调一个接一个地运行,并访问数据对象。由于循环一直在运行,因此数据总是等于最终值并记录下来。

do块通过提供闭包的简写来解决问题。代码Ionut建议在Javascript中转换为以下内容:

var data, name, _fn;

_fn = function(data) {
  return lookup(name, function(err, other_data) {
    return console.log(data);
  });
};
for (name in people) {
  data = people[name];
  console.log(name);
  _fn(data);
}

所以在这种情况下,数据被传递给一个闭包函数,该函数在其作用域中保留当前值并返回查找函数,然后该函数维护对闭包范围内值的引用。