31

I’d like to know both for regular all-in-the-family JS developer-defined functions, as well as predefined DOM methods: what happens if I try to call IE’s attachEvent with the signature of the WHATWG’s addEventListener? For instance:

elem.attachEvent('onbillgates\'mom', function(e){ this.mount(); }, false);

Specifically, note the third argument false. Will that trip anything up, even though the attachEvent method’s signature only calls for two arguments?

What about this example?

function foo(FirstOf2, SecondOf2) {
  console.log(FirstOf2 + SecondOf2);
}

foo(1, 2, true);
Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
wwaawaw
  • 6,867
  • 9
  • 32
  • 42
  • 4
    Well, what happens _when_ you try it? – lanzz Oct 02 '12 at 16:09
  • 5
    @lanzz Of course I thought to TIAS, but generally speaking testing is kind of useless if you don't have access to all environments that your code will run on, which I don't. Also, doing it this way gives me and others a deeper conceptual understanding of the language, I think. – wwaawaw Oct 03 '12 at 01:26
  • 1
    Since `attachEvent` and its two-instead-of-three arguments case is only relevant on IE, while virtually all other platforms will accept a third parameter to `addEventListener` (I'm just guessing you're going to assign one or the other to a single name), you only need to test it on an older(ish) IE, say 7.0. JS has no problem with extra arguments to functions; with IE however it is possible to have quirks, especially _if_ the function in question is an internal one and not a regular JS-sourced function. – lanzz Oct 03 '12 at 08:28

6 Answers6

27

JavaScript doesn't have the concept of a fixed parameter list. For your own functions you can always specify as many parameters as you want and pass in as many as you want which ever type you want.

For built-in functions, which correlate to native code, it depends.

You asked on what it depends:

Let's look at the ECMA-262

Section 15 about built-in (not to confuse with host) functions in general

Unless otherwise specified in the description of a particular function, if a function or constructor described in this clause is given fewer arguments than the function is specified to require, the function or constructor shall behave exactly as if it had been given sufficient additional arguments, each such argument being the undefined value.

Alright. If I pass in less arguments than needed, it depends on the spec of the function itself (scroll down section 15 to find the spec for each built-in function).

Unless otherwise specified in the description of a particular function, if a function or constructor described in this clause is given more arguments than the function is specified to allow, the extra arguments are evaluated by the call and then ignored by the function. However, an implementation may define implementation specific behaviour relating to such arguments as long as the behaviour is not the throwing of a TypeError exception that is predicated simply on the presence of an extra argument.

Passing in too many arguments should never raise a TypeError. But still it may raise other errors. Again, it depends on the function you talk about.

You were talking explicitly about the DOM and not about built-in functions. To be honest I can't find the corresponding parts of the spec. The ECMA spec is so much easier to read then the w3 website.

Prinzhorn
  • 22,120
  • 7
  • 61
  • 65
  • So DOM functions would be host functions rather than builtin functions, correct? – wwaawaw Oct 03 '12 at 12:11
  • 1
    Yes, that's correct. DOM are host objects/functions. ECMA spec says "host object: object supplied by the host environment to complete the execution environment of ECMAScript". DOM is not part of JavaScript itself. – Prinzhorn Oct 03 '12 at 12:55
  • Soooo basically the function will ignore the extra parameters unless you handle them – Kellen Stuart Oct 27 '16 at 01:48
8

Won't hurt. You can even call a function with less parameters than it takes, as long as the function code is ok with a few undefined values.

Diogo Schneider
  • 339
  • 2
  • 9
  • I'm just not sure if stuff becomes more rigid when you're dealing with the compiled "`[native code]`" of DOM methods. – wwaawaw Oct 03 '12 at 01:18
6

I came across this important, however old, question; and I hope it'll be beneficial for future generations to share my experiments with it:

  1. One can use the arguments object in order to access a function's arguments, regardless of the amount of arguments in the function's signature.
    It's worth mentioning that this doesn't apply to arrow functions:

function singleArg(x) {
  console.log(arguments);
}

singleArg(1, 2); // Called with 2 arguments
singleArg();     // Called with 0 arguments

// Results in an error, as 'arguments' isn't defined for arrow functions
((arg) => console.log(arguments))(1);
  1. It's stated in the documentation that arguments isn't exactly an Array:

“Array-like” means that arguments has a length property and properties indexed from zero, but it doesn't have Array's built-in methods like forEach() and map().

Hence the following code results in an error:

(function singleArg(x) {
  console.log(arguments); // This line works
  arguments.forEach(x => console.log(x)); // This causes an error
})(1, 2);
  1. Upon calling a function with less arguments than in its signature, they're assigned undefined:

(function twoArgs(a, b) {
  console.log(`a: ${a}\nb: ${b}`);
})(1);
GalAbra
  • 5,048
  • 4
  • 23
  • 42
1

Try taking a look at this post and perhaps this one.

From MDN:

The arguments object is a local variable available within all functions; arguments as a property of Function can no longer be used.

You can refer to a function's arguments within the function by using the arguments object. This object contains an entry for each argument passed to the function, the first entry's index starting at 0.

You can use the arguments object if you call a function with more arguments than it is formally declared to accept. This technique is useful for functions that can be passed a variable number of arguments.

function myConcat(separator) {
  var result = "";

  // iterate through non-separator arguments
  for (var i = 1; i < arguments.length; i++) {
    result += arguments[i] + separator;
  }

  return result;
}
Community
  • 1
  • 1
Chase
  • 29,019
  • 1
  • 49
  • 48
  • Just use `[].slice.call(arguments, 1).join(separator)`? – Bergi Oct 02 '12 at 16:23
  • I took the example from the MDN link to simply show what was possible. I have no doubt that there are better solutions to the `myConcat` function. =) – Chase Oct 02 '12 at 16:24
  • Right, I'm aware that this is true for native JS functions. But what about the "`[compiled code]`" of DOM methods, and especially in IE? – wwaawaw Oct 03 '12 at 01:30
0

The arguments object is an array-like object accessible inside functions that contains the values of the arguments passed to that function.

For example, if a function is passed 3 arguments, you can access them as follows:

arguments[0]; // first argument
arguments[1]; // second argument
arguments[2]; // third argument

The arguments object is useful for functions called with more arguments than they are formally declared to accept, called variadic functions. More information can be found here.

Here is a simple example of how it would look and that helped me:

<script>

function func1(a, b, c) {
  console.log(arguments[0]);
    // Expected output: 1

  console.log(arguments[1]);
    // Expected output: 2

  console.log(arguments[2]);
      // Expected output: 3

  console.log(arguments[3]);
      // Expected output: test
}

func1(1, 2, 3, 'test');

</script>
borchvm
  • 3,533
  • 16
  • 44
  • 45
-1

I don't think it will mess anything up unless you are explicitly dealing with the implicit arguments array. Why are you doing this though?

Jordan Denison
  • 2,649
  • 14
  • 14
  • I guess it has to be common with functions that accept other functions as arguments. For example the built-in Array.Prototype.forEach() method will try to pass three arguments to the passed function even if you define it as accepting only one or two arguments (which is so in most cases). – z33k Sep 28 '17 at 12:18