Call on method created in a loop always executes last method of the object

I'm using node 0.8.8 together with express 3.0.

There is an object checks with a couple of methods and an empty object middleware which should now be filled with methods, one method for each method in checks, that basically executes its check-equivalent with a couple of additional arguments.

The code looks as follows:

var checks = {

  baz: function(req, callback) {
    console.log('baz');
    callback(true);
  },

  foo: function(req, callback) {
    console.log('foo');
    callback(true);
  },

  bar: function(req, callback) {
    console.log('bar');
    callback(true);
  }

};

var middleware = {};

for (var check in checks) {

  middleware[check] = function(req, res, next) {
    checks[check](req, function(result) {
      // ...
    });
  };

}

However, no matter what method of middleware I call, the method which wraps the last method of checks is executed. That means that either middleware, although the keys are correct, is filled with the same method, or every method call on middleware executes the last method.

middleware.baz({}, function(){}); // => 'bar'
middleware.foo({}, function(){}); // => 'bar'
middleware.bar({}, function(){}); // => 'bar'

When I execute the newly created function that is assigned to middleware[check], the function is correct and wraps the one I expect. Even when I call the function assigned to middleware[check] from the last loop, the result is as expected.

for (var check in checks) {
  // ...
  middleware[check]({}, function(){});
}

// => baz
// => foo
// => bar

What am I missing?

The problem is that once your for loop has finished, the value of check is whatever the last property of checks is. You need to capture the value of check at each iteration, and you can use a closure to do so:

for (var check in checks) {
  (function (check) {
    middleware[check] = function(req, res, next) {
      checks[check](req, function(result) {
        // ...
      });
    };
  }(check));
}

Also note that you should probably add a hasOwnProperty check to that loop as it will currently enumerate any enumerable properties that are set on the prototype of checks.

As a simple demonstration, have a look at this fiddle. Check the console, then uncomment the anonymous function expression and run the code again.