imagesThe arguments object in JavaScript looks like an array, but really it is just an array-like object. It has a length property that returns the number of arguments supplied to the calling function. And callee, which actually returns the calling function. Like an array, you can access the elements using an index:

// Remember, in JavaScript you can pass as many arguments
// to a function as you want.
function example() {
  for(i=0; i < arguments.length; i++) {
    console.log(arguments[i]);
  }
}
example(true, false, 'hello', { foo: 'bar' });
// => true
// => false
// => 'hello'
// => { foo: 'bar' }

Rubyists, think *args. By allowing for optional parameters we can clean up our code interface and make it more flexible. Our methods can be more dynamic and ultimately become more useful. Lets take a look at an example, a basic getter and setter. Say we have a private variable called _status. If we want to access that value, you could do something like:

// setter
function setStatus(status) {
  return _status = status;
}
setStatus('started')); // => 'started'

and

// getter
function getStatus() {
  return _status;
}
getStatus() // => 'started'

…or you could use one method to do both:

// getter/setter
function status() {
  return arguments.length > 0 ? _status = arguments[0] : _status;
}
status(); // => 'pending'
status('started'); // => 'started'

The first part:

arguments.length > 0

Just checks to see if there are any arguments. If so, then it assigns the first argument to the private variable:

_status = arguments[0]

Otherwise, it just returns the private variable.

Again, thinking *args; arguments can be used to pass arguments straight through from one method to another. Say I am making a state machine in JavaScript. I want to be able to register states with callback functions that are triggered when the state is transitioned to. The interface for registering states might look something like this:

Mail.registerStates(
  'started',
  'finished',
  {
    // State with optional callback function
    'sent' : function(recipient) { return 'Mail sent to ' + recipient };
  }
);

When we execute the state’s callback function we can pass in the arguments:

// changes the state from 'finished' to 'sent', arguments are passed
// straight-through to the callback function
Mail.send('gob.bluth@gmail.com');
 
// Somewhere in the code
// Execute the callback function, pass the context and arguments objects
fnct.apply(this, arguments);

apply() takes the context, then an array (or array-like object) that expands as the arguments for the applicable function.

There are many possibilities with arguments, but converting it to an array provides even more flexibility. I’ve recently discovered this trick:

var args = [].concat(arguments);

Apparently arguments is enough of an array that we can operate on it with methods like concat.

That’s all for now, keep your eyes open for more articles on the dynamic features of JavaScript.

The arguments object in JavaScript

Leave a Reply