In JavaScript, each function has access to a special variable named arguments which represents any arguments which were used when calling that function.

You don’t have to define or declare arguments , it’s just already there and accessible inside the body of any JavaScript function.

This can lead to some very powerful behavior as you can write a function signature that includes only 1 argument, call the function with more, and have access to those additional arguments. For example:

var hello_name = function ( first ) { return "Hello " + first + " " + arguments [ 1 ] + " " + arguments [ 2 ] ; } ; hello_name ( "Victor" , "James" , "Quinn" ) ; "Hello Victor James Quinn"

Notice how hello_name() only has one argument declared on it, but was called with 3 and it handled all of them! Very cool! (though confusing, I certainly don’t suggest this is a good use of arguments in a case like this!)

A better real world use case is when you want a function to be able to accept an arbitrary number of arguments. Then we can iterate over each item in arguments and do something with each one. For example:

var uppercase_all_names = function ( ) { var upper = [ ] ; for ( i = 0 ; i < arguments . length ; i ++ ) { upper [ i ] = arguments [ i ] . charAt ( 0 ) . toUpperCase ( ) + arguments [ i ] . substr ( 1 ) ; } return upper ; } ; uppercase_all_names ( "victor" , "james" , "quinn" ) ; [ "Victor" , "James" , "Quinn" ]

This works, but surely we can do better! Let’s get a bit functional with map() and reduce the complexity of that code:

var uppercase_all_names = function ( ) { return arguments . map ( function ( name ) { return name . charAt ( 0 ) . toUpperCase ( ) + name . substr ( 1 ) ; } ) ; } ; TypeError : Object # < Object > has no method 'map'

Uh oh, what happened? Why can’t we use the Array map() function? It sure looks like an Array!

This is because arguments is not really an Array in spite of it having .length and being able to index its subitems like an Array.

var is_arguments_an_array = function ( ) { return arguments instanceof Array ; } ; is_arguments_an_array ( 4 , 8 , 15 , 16 , 23 , 42 ) ; false

So is it an Object?

var is_arguments_an_object = function ( ) { return typeof arguments === "object" ; } ; is_arguments_an_object ( 4 , 8 , 15 , 16 , 23 , 42 ) ; true

I suppose the answer is “kind of.” It is its own special beast that acts like an Object, but which has a length. If we inspect it it looks like an Object whose keys look like Array indices.

var inspect_arguments = function ( ) { console . log ( JSON . stringify ( arguments ) ) ; } ; { "0" : 4 , "1" : 8 , "2" : 15 , "3" : 16 , "4" : 23 , "5" : 42 }

So what do we know thus far:

We have a powerful item That is its own weird Array/Object hybrid type

But in spite of arguments being weird we can work with it and make things a bit more manageable.

The easiest way to do that is to convert it to an array. This is surprisingly convoluted, but is achieved rather easily with the following snippet:

var args = Array . prototype . slice . call ( arguments ) ;

Let’s see it in use:

var convert_arguments_to_array = function ( ) { var args = Array . prototype . slice . call ( arguments ) ; return args ; } ; convert_arguments_to_array ( 4 , 8 , 15 , 16 , 23 , 42 ) ; [ 4 , 8 , 15 , 16 , 23 , 42 ] convert_arguments_to_array ( 4 , 8 , 15 , 16 , 23 , 42 ) instanceof Array ; true

Yay! Something we can more reliably work with! Now revisiting our upper case function from above:

var uppercase_all_names = function ( ) { var args = Array . prototype . slice . call ( arguments ) ; return args . map ( function ( name ) { return name . charAt ( 0 ) . toUpperCase ( ) + name . substr ( 1 ) ; } ) ; } ; uppercase_all_names ( "victor" , "james" , "quinn" ) ; [ "Victor" , "James" , "Quinn" ]

arguments is an extremely powerful but often confusing component of JavaScript but hopefully this has helped shed some light on it!

You should follow me on twitter here.