Arguments.length In Javascript Depends On Invocation Arguments, Not Function Signatures

Posted March 24, 2011 at 9:25 AM by Ben Nadel

Tags: Javascript / DHTML

In Javascript, within a function, you can use "arguments.length" to determine how many arguments were passed-in during the given function invocation. In the past, I've used this to overload Javascript functions. Until I read Eloquent Javascript by Marijn Haverbeke, however, I don't think I had a complete understanding of how the arguments collection worked. In order to drill this information into my head, I wanted to quickly demonstrate that arguments.length relies on the invocation arguments, not the defined parameters (function signature).

Below, I am defining a function signature that contains three parameters. Then, I invoke that function with both less-than and more-than the defined number of parameters.

  • <!DOCTYPE html>
  • <html>
  • <head>
  • <title>Javascript Arguments Depend On Invocation</title>
  • <script type="text/javascript">
  •  
  •  
  • // I am a function that has THREE defined parameters.
  • function test( foo, bar, baz ){
  •  
  • // Log the length of the arguments collection.
  • console.log( arguments.length );
  •  
  • // Log the arguments collection itself.
  • console.log( arguments );
  •  
  • }
  •  
  •  
  • // -------------------------------------------------- //
  • // -------------------------------------------------- //
  •  
  •  
  • // With less than the number of defined arguments.
  • console.log( "With Two Arguments" );
  •  
  • test( "hey", "cutie" );
  •  
  •  
  • // -------------------------------------------------- //
  • // -------------------------------------------------- //
  •  
  •  
  • // With more than the number of defined arguments.
  • console.log( "With Four Arguments" );
  •  
  • test( "hey", "there", "cutie", "pie" );
  •  
  •  
  • </script>
  • </head>
  • <body>
  • <!-- Left intentionally blank. -->
  • </body>
  • </html>

When we run this code, we get the following console output:

With Two Arguments
2
["hey", "cutie"]

With Four Arguments
4
["hey", "there", "cutie", "pie"]

As you can see, the arguments collection (including the arguments.length property) depends only on the arguments used during invocation - not on the parameters defined as part of the method signature. Ironically, I've leveraged this fact before; but, like I said, I don't think I was consciously aware of the underlying mechanics.




Reader Comments

Mar 24, 2011 at 9:47 AM // reply »
29 Comments

Good call, Ben! The whole concept of a method signature doesn't seem very JavaScript, does it? In Java, the signature is critical to method binding. And even Ruby, which lets you get away with anything, complains if you don't uphold the contract in the method signature.


Mar 24, 2011 at 10:23 AM // reply »
21 Comments

If you do want to know the number of arguments that are defined for a function, so that for example you can compare what you were expecting to what you actually get, you can use something similar to the following:

function fnGreat(arg1, arg2, arg3){
console.log(fnGreat.length == arguments.length);
}
fnGreat(1, 2);

When the function isn't named, such as the following:
var fnGreat = function(agr1, agr2, arg3){
console.log(arguments.callee.length == arguments.length);
}
fnGreat(1, 2);

As "callee" is a reference to the function that was called, you can access that function's length property. According to https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope/arguments/callee it is deprecated, so if you want to be sure to get the length of a function, make sure it is a named function.


Mar 24, 2011 at 10:51 AM // reply »
11,246 Comments

@David,

And, ColdFusion is kind of in between - you can define a whole bunch of arguments, but mark some of them as optional and even give them default values. It's interesting to see how each language handles this task.

@Danilo,

Yeah, deprecating the "arguments.callee" makes recursion a bit more complex. You can no longer use anonymous functions. Named functions, as you point out, do the trick; but, sometimes, it's superfluous.


Mar 24, 2011 at 4:11 PM // reply »
54 Comments

Have you read this interesting approach to function overloading? http://ejohn.org/blog/javascript-method-overloading/

callee is removed in strict mode as it breaks encapsulation. I thought the same was true of function.length at least in becoming a deprecated or removed method.


Mar 24, 2011 at 4:32 PM // reply »
11,246 Comments

@Drew,

Thanks for the link - John always has such elegant solutions. According to the Mozilla Dev Center, I think "function.arity" is being deprecated; not sure about function.length". I've never actually used either in my code yet.... YET! :)


Mar 24, 2011 at 4:33 PM // reply »
54 Comments

@Ben, yep arity is apparently the CS notion of the arguments of a function. At least that's what I read from some arcane manuscript long before the days of duck punching :D!


Mar 24, 2011 at 4:39 PM // reply »
11,246 Comments

@Drew,

According to Wikipedia, it also applied to operators as well.


Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 24, 2013 at 5:39 PM
Ask Ben: Manually Enforcing Basic HTTP Authorization In ColdFusion
@Adam Oops! My mistake! I hadn't gotten that far in my testing - I'm still baby stepping my way through the process. ... read »
May 24, 2013 at 5:13 PM
Ask Ben: Manually Enforcing Basic HTTP Authorization In ColdFusion
Hi Jason, Thanks for checking up on that, but I still stand firm on my position. :) There are actually two listLast()'s in use, and you're right that the one using a space as a delimiter is fine. ... read »
May 24, 2013 at 4:45 PM
Ask Ben: Manually Enforcing Basic HTTP Authorization In ColdFusion
@Ben I have been lurking your site for quite some time, and haven't stepped up to comment until today. Thanks for all the great info - keep it up! @Adam I believe you are mistaken... as the commen ... read »
May 24, 2013 at 11:21 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@WebManWalking, Ha ha, let's us never speak of justifying "##" notation again :P ... read »
May 24, 2013 at 11:18 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Ben, Ah, so it was indeed how I vaguely remembered it to be: A direct assignment value = users.id[ i ] causes value to retain the sticky datatype of the query column. Although unnecessary in ... read »
May 24, 2013 at 9:11 AM
Preventing Links In Standalone iPhone Applications From Opening In Mobile Safari
@Brandon, Hi, No, I haven't been able to do that. I have just kept it as it is. ... read »
May 23, 2013 at 9:52 PM
Preventing Links In Standalone iPhone Applications From Opening In Mobile Safari
@Muhmmadibn Did you figure out a solution to launching PDFs? I am running into the same issues myself. There is no way to close the PDF or go back once you launch it. Thanks in advance! ... read »
May 23, 2013 at 6:06 PM
The Girl Who Broke My Heart, And Made Me A Better Person
Good day,ladies and gentle men, my name is Dr AMADI the great spell caster in Africa, i have help so many people for different kind of problems,who say there is no solution to problems on earth, that ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools