13
var path;

for (var i = 0, c = paths.length; i < c; i++)
{
    path = paths[i];

    fs.lstat(path, function (error, stat)
    {
        console.log(path); // this outputs always the last element
    });
}

How can I access the path variable, that was passed to fs.lstat function?

3 Answers 3

27

This is a perfect reason to use .forEach() instead of a for loop to iterate values.

paths.forEach(function( path ) {
  fs.lstat( path, function(err, stat) {
    console.log( path, stat );
  });
});

Also, you could use a closure like @Aadit suggests:

for (var i = 0, c = paths.length; i < c; i++)
{
  // creating an Immiedately Invoked Function Expression
  (function( path ) {
    fs.lstat(path, function (error, stat) {
      console.log(path, stat);
    });
  })( paths[i] );
  // passing paths[i] in as "path" in the closure
}
Sign up to request clarification or add additional context in comments.

2 Comments

Be careful with .forEach if your iterable is not exclusively formed with the elements you want to use. I'd rather be use the closure option as a general rule, IMHO.
@DanibISHOP could you expand on that? Specifically, what is "not exclusively formed with the elements"?
11

Classic problem. Put the contents of the for loop in another function and call it in the loop. Pass the path as a parameter.

Comments

1

Recursion works nicely here (especially if you have some i/o that must be executed in a synchronous manner):

(function outputFileStat(i) {
    var path = paths[i];

    fs.lstat(path, function(err, stat) {
         console.log(path, stat);
         i++;
         if(i < paths.length) outputFileStat(i);
    });
})(0)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.