This is actually more of a closure problem than a scope problem. What happens is that when you define a function in javascript ( coffeescript too, of course ) the function remembers context it was created in, including all variables in parent scopes. But what is has are not copies of variables but references of those variables.
Callback from Datum.findOne
is going to be called after your for
loop has finished iterating. This means the offset
variable has already been incremented. You can easily prevent this be wrapping an annonymous function around Datum.findOne
, like this:
for offset in [1..3]
do ( offset = offset ) ->
Datum.findOne { date: { $lte: queryDate.toDate() } }, (err, datum) ->
console.log offset
Passing a variable as an argument to function will create it's copy.
I belive that defining the function inside loop is better for readabilty, but if the function is big, or if the loop has many iterations it's actually better to define it elswhere.
//edit: Actually, coffeescript will define it outside the loop.
You might want to refer to this question to read up on closures.