Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I'm writing a function that takes between one and three arguments (function callback [, number limit] [, regexp pattern]). Since the second two are both optional, I need to determine which arguement is being passed when the function is supplied with only two. Below is my solution, but it seems overly verbose. Is there a cleaner way to do this?

  var get_queued_pages = function() {
    if(arguments>0){
        var callback = arguments[0]; 
        if(arguments.length == 3){ //all arguments are being passed     
        var limit    = arguments[1];
        var pattern  = arguments[2];
        }
        else if(arguments.length == 2){ //only 2 arguments passed
        if(typeof(arguments[1]) == "number"){ //check if the second one is limit or pattern             
            var limit = arguments[1];//no pattern defined; second argument is limit
        }
        }
        else{
        var limit = 1;
        }
    }
    //do stuff

}
share|improve this question
    
Can the order of which they are passed in change? Ie. if there is a second one, will it always be a number etc. Or could the order change possibly? Being were the regexp gets passed in first or vice versa. –  Jonny Sooter Mar 13 '13 at 14:33
    
In this example, no. If there is a way to elegantly handle that too it would be extra nice though! –  devnill Mar 13 '13 at 14:42

2 Answers 2

up vote 3 down vote accepted
function(cb,limit,pattern) {
    limit = typeof(limit) === "undefined" ? 1 : limit;
    //do stuff
}

Calling a function with less arguments than declared will just fill them with undefined. You can then check if that is the value, if so fill in your default ones.
The I have above will have the same affect as yours, there are always three variables (even in your code, Javascript variables are function scope, all of the var declarations are pulled to the top.).
The variables:
cb - unchanged
limit - set to 1 if not supplied pattern - unchanged (undefined if not supplied)

EDIT: I just saw your comment on reordering you can do the following

  function foo(cb,limit,pattern) {
        if(limit instanceof RegExp) {
            pattern = limit;
            limit = 1;
        }
        else {
            limit = typeof(limit) === "undefined" ? 1 : limit;
        }
        //do stuff
    }
share|improve this answer
    
That looks quite nice! Thanks! –  devnill Mar 13 '13 at 18:50

One thing I did notice in your code is that you're testing if arguments > 0. I assume you mean arguments.length > 0.

Anyway, for simple stuff like this, you don't really need to use arguments.length.

In JavaScript, if you have a function that takes, say three arguments:

function doSomething(callback, limit, pattern) {
   // do something
}

You can still call it passing one argument:

doSomething(foo);

What will happen is that inside the function body, the first parameter will be set and other parameters will be undefined. The easiest/shortest way to implement what you want is simply to check if limit and pattern are not undefined:

if (typeof(limit) != 'undefined') { ... }

arguments is better suited for more complicated variadic functions (think of printf in C, for example, or console.log in JavaScript) that may take arbitrary numbers of arguments.

share|improve this answer
    
You are correct, I did forget length. I see what you are saying in your example, but what if only the first and third arg were passed? Is it a better practice to leave the argument names ambiguous so pattern isn't defined as limit? –  devnill Mar 13 '13 at 18:48

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.