Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect a JavaScript function with a certain signature has been registered?

Tags:

javascript

Say you have two functions with the following signatures:

  1. addClass( class )
  2. addClass( class, duration )

These live in a third party library (no prizes for guessing which!!).

If you call addClass() with two parameters but only have signature 1 registered, there will be no error and signature 1 will be called. The second parameter is ignored.

So is there a way to detect that signature 2 with two parameters has been registered?

like image 848
Alex Angas Avatar asked Jan 28 '11 21:01

Alex Angas


3 Answers

You can use the length property of the function object to check the signature. Example:

function x(a) {}
function y(a,b) {}

alert(x.length); // shows "1"
alert(y.length); // shows "2"
like image 121
Guffa Avatar answered Nov 14 '22 18:11

Guffa


There is no native method overloading in JavaScript. You can create your own, though: http://ejohn.org/blog/javascript-method-overloading/

(Update 11/5/15: The link seems to be dead, here's the Google Cache version)

So if you do

function addClass( class ) { console.log('1 arg'); };
function addClass( class, duration ) { console.log('2 args'); };

the second one overwrites the first one. So even if you call "addClass(1)", the output will still be "2 args". Same as doing

someObject.addClass = function(a) {...}
someObject.addClass = function(a, b) {...}

The first "version" will be lost.

like image 9
Johannes Fahrenkrug Avatar answered Nov 14 '22 19:11

Johannes Fahrenkrug


It isn't very difficult to achieve, but Resig's method isn't up to much, as it only checks for arguments length, which is only tangentially related to real call signatures.

Johannes method is actually method overriding not multiple call signatures, and anyway will fail in JS Strict mode where multiple function declaration of the same name are forbidden.

To implement properly you'll need to implement it via call forwarding, wrapping each call signature in a type/existence check:

function myFunction(arg1, arg2, arg3){
  switch(true){
    case arg1 instanceof someObject:
        myFunction_signature1.apply(this, arguments);
        break;
    case typeof arg1 === "string":
        myFunction_signature2.apply(this, arguments);
        break;
    }
}

It gets a little more complex when some params are optional as well.

like image 3
Neil Avatar answered Nov 14 '22 18:11

Neil