javascript - 在函数上使用.apply的问题

时间:2014-01-28 01:35:06

标签: javascript

好的,所以我有一个对象,我想将回调函数应用于对象中的所有方法。这是我到目前为止所尝试的:

var namespace = { 
  foo : 'bar', 
  foobar :  function() { console.log('call from foobar!')},
  someFunc : function() { console.log('call from someFunc!')},
  someFunc2 : function() { console.log('call from someFunc2!')}
}

var logger = {
  _callback : function () {
    console.log('call from logger!',arguments);
  }
}

for (var m in namespace) { 
  if ( namespace.hasOwnProperty(m) && (typeof namespace[m]=='function') ) {
    logger[m] = namespace[m];
    namespace[m] = function() {
      logger._callback(arguments);
      logger[m].apply(this, arguments);
    }
  }
}

namespace.foobar('foo');
namespace.someFunc('bar');
namespace.someFunc2('bar2');

这是登录到控制台的内容:

call from logger! [["foo"]]
call from someFunc2!
call from logger! [["bar"]]
call from someFunc2!
call from logger! [["bar2"]]
call from someFunc2!

正如您所看到的,由于某种原因,namespace的所有3种方法都输出'call from someFunc2!这是错误的。我不确定这里的问题是什么。我做错了什么?

2 个答案:

答案 0 :(得分:5)

只有一个“m”。您在for循环中创建的函数内部的代码引用“m”的“实时”值,而不是在创建函数时冻结的值。它所采用的最后一个值是名称“someFunc2”,因此这就是被调用的值。

一步一步:

  1. 您可以创建“命名空间”和“记录器”对象。
  2. 循环运行。变量“m”接受“namespace”对象中属性的连续值,并为该对象的每个相关属性创建一个新函数。
  3. 在循环结束时,“m”的值为“someFunc2”。
  4. 您调用其中一个“命名空间”函数。这将是对循环中创建的函数之一的调用。该函数将依次调用“_callback”函数。现在重要的关键点是:它使用“m”的值引用“logger”对象的属性。 “m”的价值是多少?这是“someFunc2”。

答案 1 :(得分:5)

尝试

for (var m in namespace) { 
   if ( namespace.hasOwnProperty(m) && (typeof namespace[m]=='function') ) {
      logger[m] = namespace[m];
      (function(index){
         namespace[index] = function() {
           logger._callback(arguments);
           logger[index].apply(this, arguments);
         };
      })(m);
   }
}

否则namespace[m] = function(){}将使用m是最后一个