调用循环中创建的方法总是执行对象的最后一个方法

时间:2012-09-01 18:46:39

标签: javascript node.js express

我正在使用节点0.8.8和express 3.0。

有一个对象checks有几个方法和一个空对象middleware现在应该填充方法,checks中每个方法的一个方法,基本上执行它check - 相当于一些额外的参数。

代码如下:

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) {
      // ...
    });
  };

}

但是,无论我调用middleware的哪种方法,都会执行包装checks的最后一个方法的方法。这意味着middleware虽然键是正确的,但是使用相同的方法填充,或者middleware上的每个方法调用都执行最后一个方法。

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

当我执行分配给middleware[check]的新创建的函数时,该函数是正确的并且包装了我期望的函数。即使我从最后一个循环中调用分配给middleware[check]的函数,结果也是预期的。

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

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

我错过了什么?

1 个答案:

答案 0 :(得分:3)

问题在于,for循环完成后,check的值就是checks的最后一个属性。您需要在每次迭代时捕获check的值,并且可以使用闭包来执行此操作:

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

另请注意,您应该在该循环中添加hasOwnProperty检查,因为它当前将枚举checks原型上设置的任何可枚举属性。

作为一个简单的演示,请看this fiddle。检查控制台,然后取消注释匿名函数表达式并再次运行代码。