Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript convention for variable length arguments

I am getting more in to javascript development, and want to ensure I am following popular conventions. Currently I have a library which consists of functions that can be passed either 1 model to operate on, or many models.

Given the climate that a few javascript libraries are very popular, I am curious; would I be conforming to the 'defacto standard' by achieving my 'single-item or list-of' requirement, by enumerating the arguments variable, or by allowing one of the arguments to be an array?

Scenario 1: argument enumeration

// passing a single entity to my function
sendMail( email, recipient1 );

// passing multiple entities to my function
sendMail( email, recipient1, recipient2 );

Scenario 2: entity argument is either single instance, or array

// pass a single entity
sendMail( email, recipient1 );

// passing multiple entities
sendMail( email, [recipient1, recipient2] );

I have seen areas of jQuery which use 'scenario 2', but I would still like to ask - which approach is the most popular, and why?

Thanks

[EDIT]

A couple of comments have followed the same vein, of using an arguments object - which is similar to 'scenario 2' - but I feel it introduces unnecessary complexity - the elements dont need to be named, because they are just a variable length list. I thought I would just add that here in case my question wasn't clear enough.

[EDIT]

I see code like this all through jQuery-1-7.js

queue: function( elem, type, data ) {
    var q;
    if ( elem ) {
        type = ( type || "fx" ) + "queue";
        q = jQuery._data( elem, type );

        // Speed up dequeue by getting out quickly if this is just a lookup
        if ( data ) {
            if ( !q || jQuery.isArray(data) ) {
                q = jQuery._data( elem, type, jQuery.makeArray(data) );
            } else {
                q.push( data );
            }
        }
        return q || [];
    }
}

[EDIT]

After some discussion with JP, I came up with this - which I'm not saying is the right choice, but it is very flexible...

lastArgumentAsParams: function()
{
    var callerArgs = jQuery.makeArray(this.lastArgumentAsParams.caller.arguments);

    // return empty set if caller has no arguments
    if ( callerArgs.length == 0 )
        return [];
     callerArgs.splice(0, callerArgs.length - 1)
    // remove all but the last argument
    if ( callerArgs.length == 1 && jQuery.isArray(callerArgs[0]))
        return callerArgs[0];
    else
        return callerArgs;
}

If you call this function at the beginning of any function - it will treat the last arg in the caller as a 'variable length argument' - supporting any of the conventions.

For example, I can use it like this

function sendEmail( body, recipients )
{
    recipients = lastArgumentAsParams();

    // foreach( recipient in recipients )...
}

Now, I can call 'sendEmail' in any of the following ways and it will work as expected

sendEmail('hello world', "[email protected]" );
sendEmail('hello world', "[email protected]", "[email protected]" );
sendEmail('hello world', ["[email protected]", "[email protected]"] );
like image 217
Adam Avatar asked Mar 06 '12 20:03

Adam


People also ask

What is arguments length in JavaScript?

The arguments.length property provides the number of arguments actually passed to a function. This can be more or less than the defined parameter's count (see Function.prototype.length ).

What are the variable-length arguments?

Variable-length arguments, varargs for short, are arguments that can take an unspecified amount of input. When these are used, the programmer does not need to wrap the data in a list or an alternative sequence.

What are the variable conventions available in JavaScript?

Naming ConventionsVariable and function names written as camelCase. Global variables written in UPPERCASE (We don't, but it's quite common) Constants (like PI) written in UPPERCASE.


1 Answers

I personally prefer using object literals for arguments to support named params, like this:

var myfunc = function(params){ //same as: function myfunc(params){....
  alert(params.firstName);
  alert(params.lastName);   
};

myfunc({firstName: 'JP', lastName: 'Richardson'});

I think that it makes code very readable and order won't matter.

OR

You can also access the arguments object. Note, it's not an array, but it's "array-like". You can read about it here: http://javascriptweblog.wordpress.com/2011/01/18/javascripts-arguments-object-and-beyond/

Edit:

You seem to have a misunderstanding here. You're using the phrase "arguments object" and are thinking that it's the same as object literal notation. They are not.

The arguments object allows you to do this:

function myfunc(){
  alert(arguments[0]); //JP
  alert(arguments[1]); //Richardson 
}

myfunc('JP', 'Richardson');

Does that help?

like image 113
JP Richardson Avatar answered Nov 03 '22 17:11

JP Richardson