Javascript argument collections within closures
Posted by Steve Brownlee on September 17, 2009Sep 17
I have to say, it’s been a refreshing break to work on one of our older apps that was written pre-Flex. Working on my old jQuery/ExtJS Javascript code has been fun and I’ve been able to add some new tricks I’ve learned in the last year and a half.
One little tidbit that I thought I’d pass along is a simple trick that most Javascript developers know how to do, but may trip up someone just getting into advanced Javascript development with some of the major libraries out there.
Knowing the proper scope of your Javascript variables is a task that everyone who’s worked with the language knows is important. Using libraries like jQuery and ExtJS make it a bit tricker. An example is when you want to pass an entire argument collection from one function to another and then use that argument collection inside a closure for, say, an ExtJS MessageBox.
At first, you may have the desire to simply pass the argument array from the first function to the second.
function confirm(one, two, three, four) {
Ext.MessageBox.show({
title: 'Confirmation',
msg: 'Please confirm that you want to delete this.',
buttons: Ext.MessageBox.YESNO,
fn: function (btn) {
if(btn == 'yes') doAction(arguments);
}
});
}
function doAction(one, two, three, four) {
$.AjaxCFC({
url: "com/acme/Widget.cfc",
method: "delete",
data: { 'one':one,
'two':two,
'three':three,
'four':four
}
});
}
But the execution block that actually calls the doAction() method in within a closure inside the main confirm() method. What this means is that the argument array actually contains the arguments for that anonymous function to handle the button click on the confirmation message.
What you need to do is preserve the arguments collection in a variable scoped to the confirm() method – which is available to the closure (one of the strengths of Javascript) – which can then be passed to the doAction() method.
You then use the apply() method on the function (the apply() method allows you to pass the arguments array) and pass that holding variable.
function confirm(one, two, three, four) {
var args = arguments;
Ext.MessageBox.show({
title: 'Confirmation',
msg: 'Please confirm that you want to delete this.',
buttons: Ext.MessageBox.YESNO,
fn: function (btn) {
if(btn == 'yes') doAction.apply(this, args);
}
});
}
function doAction() {
var args = arguments;
$.AjaxCFC({
url: "com/acme/Widget.cfc",
method: "delete",
data: { 'one':args[0],
'two':args[1],
'three':args[2],
'four':args[3]
}
});
}
Javascript is such a beautiful and powerful language. I have to say I’ve missed working with it.


Nice post. This same thing used to trip me up with the “this” keyword as well. Sometimes you find yourself inside of another scope before you even know what’s going on