简体   繁体   中英

javascript - issue with using .apply on functions

Okay so I have an object and I want to apply a callback function to all of the methods in the object. This is what I have tried so far:

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');

This is what is getting logged to the console:

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

As you can see, for some reason all 3 methods of namespace are outputting 'call from someFunc2! which is wrong. I'm not sure what the issue here is.. what am I doing wrong?

There's just one "m". The code inside that function you create in the for loop references the "live" value of "m", not a value frozen at the point the function was created. The last value it takes on is name "someFunc2", so that's the one that's called.

Step by step:

  1. You create the "namespace" and "logger" objects.
  2. The loop runs. The variable "m" takes on the successive values of the properties in the "namespace" object, and creates a new function for each relevant property of that object.
  3. At the end of the loop, "m" has the value "someFunc2".
  4. You call one of the "namespace" functions. That'll be a call to one of the functions created in the loop. That function will in turn call the "_callback" function. And now the important key point: it references a property of the "logger" object using the value of "m". What is the value of "m"? It's "someFunc2".

Try

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);
   }
}

otherwise the namespace[m] = function(){} will use whatever m is last

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM