0

Following the jQuery plugin pattern, how can one find the arity of a function, say the methods.myfunc function, in the case where we've used apply() to define the scope of this and applying arguments to this?

(function($, window, document ){

"use strict";
//...
methods = {
  myfunc: function(){
    // myfunc.length? tried, didnt work
    // arguments.length? tried, didnt work
    // methods.myfunc.length? tried, didnt work
    // arguments.callee tried, doesnt work in strict mode
  }
  //...
}

$.MyPluginThing = function( method ){

  if( methods[method] ){
      return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
  }else if( typeof method === "object" || ! method ){
      return methods.init.apply( this, arguments, window );
  }else{
      $.error( "Method " +  method + " does not exist on jQuery.MyPluginThing" );
  }

}...

This may expose some of my ignorance with function scope, but I'm pretty stumped here, and have not found an example that explains this well enough.

Part of my inspiration for this question comes from NodeJS/ExpressJS, where they have a variable number of arguments for some functions. If 3 arguments are passed, for example, it's assumed there is an error object, but you could just as easily pass two and there's no problem!

update: changed function in code from init to myfunc

Community
  • 1
  • 1
qodeninja
  • 10,946
  • 30
  • 98
  • 152

1 Answers1

3

You'll have to use a named function expression (with all its idiosyncrasies):

var methods = {
  init : function init () {
    var arity = init.length;
  }
};

Here's the fiddle: http://jsfiddle.net/tqJSK/

To be honest though, I have no idea why you'd ever need this. You can hard code that number within the function, since the amount of named arguments will never change...


Update: as pointed out by @T.J.Crowder, you can use regular function declarations instead:

(function($, window, document) {

    function init () {
        var arity = init.length;
    }

    var methods = {
      init : init
    };

}(jQuery, window, document));

Update 2: if all you're looking for is the number of arguments supplied in this specific call, just use arguments.length:

var methods = {
  init : function () {
    var count = arguments.length;
  }
};

Here's the fiddle: http://jsfiddle.net/tqJSK/1/

Joseph Silber
  • 214,931
  • 59
  • 362
  • 292
  • for some reason, when I did myfunc.length I kept getting 0! – qodeninja Jan 13 '13 at 07:55
  • 1
    @qodeninja: The function in your question has no declared arguments, so `length` would indeed be `0`. – T.J. Crowder Jan 13 '13 at 07:57
  • @T.J.Crowder so you have to declare your arguments, you can't have a variable length? – qodeninja Jan 13 '13 at 07:58
  • @ Joseph: It doesn't *have* to be a named function expression. It could be a function declaration elsewhere, then used as the value of the `init` property. – T.J. Crowder Jan 13 '13 at 07:58
  • 1
    @qodeninja: You can use `arguments` if the number of arguments varies (yes, in strict mode). The arity of a function is the number of its *declared* arguments, not the number of its actual arguments. That's `arguments.length`. – T.J. Crowder Jan 13 '13 at 07:59
  • @T.J.Crowder - Of course. But that adds *so much* unnecessary complexity for very little gain. – Joseph Silber Jan 13 '13 at 07:59
  • @JosephSilber: Oh, I completely disagree, but we can leave it there. :-) – T.J. Crowder Jan 13 '13 at 08:00
  • @T.J.Crowder - `arguments.length` will return the number of arguments supplied to the function *call*. `functionName.length` returns the amount of arguments formally declared (its arity), which is what the OP wants. – Joseph Silber Jan 13 '13 at 08:00
  • @JosephSilber: Yes, that's what I just told qodeninja. – T.J. Crowder Jan 13 '13 at 08:01
  • They do this variable arity thing in NodeJS/ExpressJS, and I was playing around with how it might work in a jQuery plugin. – qodeninja Jan 13 '13 at 08:01
  • @qodeninja: Arity is not variable. You're using the wrong term, see above. If your goal is to respond to the number of actual arguments given to the function on a particular call, that's `arguments.length`: http://jsbin.com/ominir/1/edit – T.J. Crowder Jan 13 '13 at 08:02