A slight diversion in our quest to learn JavaScript from a C# programmer's perspective.
This episode is about the arguments
array.
In C#, if we want to write a method that takes an undefined (at least at compile-time) number of parameters, we use the params
keyword and declare a parameter array.
static void ListArgs(params string[] args) { Console.Write(string.Format("There are {0} parameters: ", args.Length)); for (int i = 0; i < args.Length; i++) { Console.Write(args[i] + " "); } Console.WriteLine(); } static void Main(string[] args) { string[] words = {"one", "two", "three"}; ListArgs(words); ListArgs("hello", "world"); ListArgs(); Console.ReadLine(); }
Here we have a ListArgs
method whose only parameter is a parameter array of strings, called unimaginatively args
. The method merely outputs the number of parameters, and the values of each of them. The Main
method calls this method in three different ways, first with an array of strings, then with two string parameters, then with nothing at all. In the first case, the compiler ensures the method is called with the given array. In the second case, the compiler inserts code to create an array containing the two parameters, and then calls ListArgs
. In the third case the compiler creates an empty array and passes it in.
In all cases, the output is as we expect.
In JavaScript, no matter how we declare the parameters to a function, when we call it we always get a variable called arguments
automatically created for us that contains all the parameters passed in.
One reason for this is that JavaScript is very loose in how it treats parameters. If you declare a function with two parameters, say, you can call it with exactly two parameters as you'd expect, but you can also call it with fewer than two parameters, or with more than two parameters. In the first case, any parameters that were not provided by the caller will be set to undefined
inside the function; in the second case, the extra parameters are just ignored.
Nevertheless, in that second case, we can discover the extra parameters by using the arguments
array. JavaScript will construct this pseudo-array to contain all the parameters passed to the function.
Here's the JavaScript equivalent of the ListArgs
method:
var ListArgs = function() { var logstring = "There are " + arguments.length + " parameters: "; for (var i = 0; i < arguments.length; i++) { logstring += arguments[i] + " "; } console.log(logstring); }; ListArgs("hello", "world"); ListArgs();
The call with a string array doesn't really translate: we'd have to check internally to the function to see if a particular parameter were an array and deal with it accordingly. Anyway, you can see that ListArgs
is defined not to accept any formal parameters at all. Nevertheless, we can get at them by using the arguments
pseudo-array.
I want to stress that arguments
, although it looks like an array, isn't. It's an object, certainly, and it has a length
property and its properties are numbers sequentially increasing from '0'
, but that's only as deep as the deception goes. A lot of times, it doesn't really matter that arguments
is not an array (those properties I mentioned are usually enough to be getting on with), but sometimes you'll find yourself caught out and need some array methods. In that case you'll have to copy the elements to a real array, or you'll have to use the apply
method to use an array method on the arguments
object.
Because arguments
(and this
for that matter) are created when a function is called, they are locked in scope to that call of that function. They do not participate in the normal function scoping. Which is obvious, if you think about it: if you have a function B nested in function A, then any reference to arguments
in B will use B's arguments
object and not A's. If you want to share A's arguments
with B, then you'll need to copy them to a local variable in A.
Now playing:
New Order - World
(from (the best of) New Order)
4 Responses
#1 Dew Drop – March 9, 2009 | Alvin Ashcraft's Morning Dew said...
09-Mar-09 5:37 AMPingback from Dew Drop – March 9, 2009 | Alvin Ashcraft's Morning Dew
#2 JavaScript for C# programmers: the arguments array : Algorithms for the masses - Julian M Bucknall said...
09-Mar-09 6:05 PMThank you for submitting this cool story - Trackback from DotNetShoutout
#3 Saeed Neamati said...
29-Dec-11 1:06 AMGood article, thanks. However, I now need a method to dynamically get the list of all parameters passed to a method, and then loges them all. For example, I'd like to have:
#4 julian m bucknall said...
03-Jan-12 11:58 AMSaeed: I have this down as a quick blog post this week. Stay tuned!
Cheers, Julian
Leave a response
Note: some MarkDown is allowed, but HTML is not. Expand to show what's available.
_emphasis_
**strong**
[text](url)
`IEnumerable`
* an item
1. an item
> Now is the time...
Preview of response