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 »
10,743 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 »
10,743 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 »
10,743 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
InVision App - Prototyping Made Beautiful With Prototyping Tools Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 21, 2012 at 1:58 AM
Updated: Converting A ColdFusion Query To CSV Using QueryToCSV()
Hi Ben, why do you need to have so many double quotes when adding the field and field name to the row data? ----------------------------------------- <cfset LOCAL.RowData[ LOCAL.ColumnIndex ] = ... read »
AXL
May 21, 2012 at 1:24 AM
URL Rewriting And ColdFusion's WriteToBrowser Image Functionality (CFFileServlet)
@Mounir, Open your lower case URL Rewrite rule and add the following condition. Condition input: {REQUEST_URI} Check if input string: Does Not Match the Pattern Pattern: ^/CFFileServlet/_cf_ca ... read »
May 20, 2012 at 4:28 AM
Understanding The Complex And Circular Relationships Between Objects In JavaScript
@Will Vaughn I tried your javascript example but got this error:- foo.print is not a function ... read »
May 19, 2012 at 5:37 AM
A Graphical Explanation Of Javascript Closures In A jQuery Context
Thanks for this article, but I fear you missed an important point. If variables in the outer context change, these changes affect the inner anonymous functions as well. That means: if you change the ... read »
May 18, 2012 at 3:39 PM
Parsing CSV Data With An Input Stream And A Finite State Machine
Can you use file upload button with this? and read live? or does the file have to already be on the server saved? ... read »
May 18, 2012 at 1:06 AM
VIRGO (Aug. 23-Sept. 22): Dead On The Money!
A friend of mine and I were arguing about astrology and she told me that he believes in astrology. She hasn't provided me with any evidence that the belief makes any sense to me. She she been telling ... read »
May 17, 2012 at 11:32 PM
Using ColdFusion to Handle 404 Errors (Page Not Found) On Development Server
Very easy the configuration. I read a lot pages and I can't find the solution. I open the administrator and change this Administrator/server settings/Error Handlers/Missing Template Handler and p ... read »
May 17, 2012 at 3:13 PM
LOCAL Variables Scope Conflicts With ColdFusion Query of Queries
I never cease to be amazed that almost EVERY random CF issue I come across lands me on your site. Thank you for documenting your findings for the world. ... read »