2

In PHP every class contains a "magic" __call function. Using this one can dynamically intercept all calls to a class. For example using

class TestClass {

    public function __call($functionname, $arguments) {

        .. functionname called 

    }

}

See http://www.php.net/manual/en/language.oop5.overloading.php#object.call

Is something similar possible in JavaScript/Node.js? Either on a module (loaded by require) or for classes?

Update: Thank you for all who commented. This does not seem to be possible in pure JavaScript. At least currently.

Community
  • 1
  • 1
user2692274
  • 145
  • 2
  • 5
  • You'll have to wait for the next version of ECMAScript to have that. – bfavaretto Aug 30 '13 at 21:33
  • @user2692274 he is referring to `class` and `public` I believe – pllee Aug 30 '13 at 21:38
  • 1
    @pllee No, I'm referring to [direct proxies](http://wiki.ecmascript.org/doku.php?id=harmony:direct_proxies) – bfavaretto Aug 30 '13 at 21:42
  • @bfavaretto that is interesting stuff and looks like nicer syntax but intercepting methods can be done all versions on ECMAScript. – pllee Aug 30 '13 at 21:48
  • @pllee: Yes. Ideally I was hoping to replicate the above php code, and intercept the function names of _all_ calls to some class/module. – user2692274 Aug 30 '13 at 21:49
  • @user2692274 yes that can be done. The answer below can be applied to classes and modules. – pllee Aug 30 '13 at 21:51
  • @pllee How can you reproduce `__call` in current js? It's supposed to intercept calls to `someInstance.nonExistingMethod()`. – bfavaretto Aug 30 '13 at 21:51
  • @bfavaretto I've never heard of `__call` until now and maybe I am misunderstanding it but you could intercept all methods on an instance. The intercepting method would call `__call` and then the method it just intercepted by doing `return oldMethod.apply(this, arguments)` – pllee Aug 30 '13 at 21:57
  • @pllee You're talking about intercepting/overloading existing methods, but `__call` allows you to intercept calls to non-existing methods (see [docs](http://br2.php.net/manual/en/language.oop5.overloading.php#object.call)). You can't do that in js, `var o = {}; o.foo()` throws an error. In PHP, you can intercept such a call with the magic `__call` method. – bfavaretto Aug 30 '13 at 22:00
  • @user2692274 I didn't realize you were asking about Node specifically! You can enable that feature in Node, see http://stackoverflow.com/questions/10665892/enable-harmony-proxies-in-nodejs – bfavaretto Aug 30 '13 at 22:13
  • @bfavaretto You are right I thought `all calls to a class` meant all method calls. The php docs clear it up. – pllee Aug 30 '13 at 22:24

1 Answers1

2

You could do something like this, though it's per-function:

// original module
var module = {
   myFunc: function(){ /* ... */ }
}

// "spying" code

var originalFunction = module.myFunc;

module.myFunc = function(){
    // DO SPY STUFF HERE

    return originalFunction.apply(this, arguments);
};

http://jsfiddle.net/9eu45/

Kirby
  • 15,127
  • 10
  • 89
  • 104
James Montagne
  • 77,516
  • 14
  • 110
  • 130
  • Thank you for pointing this out. I was not aware of this functionality. Unfortunately, it is not quite was I am looking for. This might be useful later though! – user2692274 Aug 31 '13 at 08:31