# Function arguments

In JavaScript, a function may be called with any number of arguments, no matter how many of them are listed.

For instance:

 `1` `function` `go(a,b) {`
 `2` `  ``alert(``"a="``+a+``", b="``+b)`
 `3` `}`
 `4`
 `5` `go(1)     ``// a=1, b=undefined`
 `6` `go(1,2)   ``// a=1, b=2`
 `7` `go(1,2,3) ``// a=1, b=2, extra argument is not listed`

Arguments which are not provided become `undefined`. So we can see if the function is called with no arguments:

 ` ` `function` `check(x) {`
 ` ` `alert(x === undefined) ``// ok now I know there is no x`
 `}`
 `4`
 `5` `check()`

No syntax-level polymorphism

In some languages, a programmer may write two functions with same name but different parameter list, and the interpreter/compiler would choose the right one:

 `01` `function` `log(a) {`
 `02` `  ``...`
 `03` `}`
 `04`
 `05` `function` `log(a,b,c) {`
 `06` `  ``...`
 `07` `}`
 `08`
 `09` `log(a) ``// first function is called`
 `10` `log(a,b,c) ``// second function is called`

That is called function polymorphism. In JavaScript, there’s no such thing.

There can be only one function named `log`, which is called for any given arguments.

## Accessing the unnamed arguments

How do we get more arguments than listed in parameters?

There is a special pseudo-array inside each function called arguments.

It contains all parameters by their number: `arguments[0]``arguments[1]` etc.

Here is an example of how to list all arguments, no matter how many of them:

 `1` `function` `sayHi() {`
 `2` `  ``for``(``var` `i=0; i
 `3` `    ``alert(``"Hi, "` `+ arguments[i])`
 `4` `  ``}`
 `5` `}`
 `6` ` `
 `7` `sayHi(``"Cat"``, ``"Alice"``)  ``// 'Hi, Cat', then 'Hi, Alice'`

All parameters are in `arguments`, even if the function names some of them: `sayHi(a,b,c)`.

## The guts of `arguments`

A frequent beginner mistake is to use `Array` methods on it. Shortly, you can’t:

 `1` `function` `sayHi() {`
 ` ` `  ``var` `a = arguments.shift() ` `// error! arguments is not Array`
 `3` `  ``alert(a)`
 `4` `}`
 `5`
 `6` `sayHi()`

If it isn’t `Array`, then what it is? Let’s use the [[Class]] property to see it:

 `1` `(``function``() {`
 `2`
 `3` `  ``alert( {}.toString.call(arguments) )  ` `// [object Arguments]`
 `4`
 `5` `})()`

This type is internally almost same as `Object`. It only looks like array, because it’s keys are numeric and it has `length`, but here the similarity ends.

## Using `arguments` as `Array`

There is still a way to call array methods on `arguments`:

 `1` `function` `sayHi() {`
 `2` `  ``var` `args = [].join.call(arguments, ``':'``)`
 `3` `  ``alert(args)  ``// 1:2:3`
 `4` `}`
 `5`
 `6` `sayHi(1,2,3)`

Here we execute the join method of `Array` in the context of `arguments`, providing `':'` as first argument.

It works, because internally most array methods (and `join`) use numeric indexes and `length` to work.

The `join` would work on a custom object as well, if the format is correct:

 `1` `var` `obj = { 0: ``"A"``, 1: ``"B"``, length: 2 }`
 `2`
 `3` `alert( [].join.call(obj) ) ``// "A,B"`

## Making a real `Array`

The arr.slice(start, end) copies the part of `arr` from `start` to `end` into the new array.

It can be called in the context of `arguments` to copy all elements into a real array:

 `1` `function` `sayHi() {`
 `2` `  ``var` `args = [].slice.call(arguments) ` `// slice without parameters copies all`
 `3`
 `4` `  ``alert( args.join(``':'``) ) ``// now .join works`
 `5` `}`
 `6`
 `7` `sayHi(1,2)`

The `arguments` and named parameters reference same values.

Updating `arguments[..]` causes the corresponding parameter to change and vice versa. For example:

 `1` `f(1)`
 `2`
 `3` `function` `f(x) {`
 `4` `  ``arguments[0] = 5`
 `5` `  ``alert(x) ``// 5, updating arguments changed x`
 `6` `}`

And the reverse way:

 `1` `f(1)`
 `2`
 `3` `function` `f(x) {`
 `4` `  ``x = 5`
 `5` `  ``alert(arguments[0]) ``// 5, update of x reflected in arguments`
 `6` `}`

`Array` methods which modify `arguments` also modify local parameters:

 `1` `sayHi(1)`
 `2`
 `3` `function` `sayHi(x) {`
 `4` `  ``alert(x)           ``// 1`
 `5` `  ``[].shift.call(arguments) `
 `6` `  ``alert(x)           ``// undefined, no x any more :/ `
 `7` `}`

Actually, the modern ECMA-262 5th specification splits arguments from local variables. But as of now, browsers still behave like described above. Try the examples to see.

Generally, it is a good practice not to modify `arguments`.

## Default values

If you want a function parameter to be optional, there are two ways.

1. First, you could check if for `undefined` and reassign:
 `1` `function` `sayHi(who) {`
 `2` `  ``if` `(who === undefined) who = ``'me'`
 `3` `    `
 `4` `  ``alert(who) `
 `5` `}`
2. Or, use the OR `||` operator:
 `1` `function` `sayHi(who) {`
 `2` `  ``who = who || ``'me'`  `// if who is falsy, returns 'me'`
 `3` `    `
 `4` `  ``alert(who) `
 `5` `}`
 `6` `sayHi(``"John"``)`
 `7` `sayHi()  ``// 'me'`

This way works great for parameters which are either not given or true. It happens most of time in real life.

A well-known function with variable number of arguments is `Math.max`. It returns the greatest or it’s arguments:

 `1` `alert( Math.max(1, -2, 7, 3) )`

Use `func.apply(context, args)` and `Math.max` to find the greatest element of an array:

 `var` `arr = [1, -2, 7, 3]`
 `/* your code to output the greatest value of arr */`

Solution

The solution:

 `1` `var` `arr = [1, -2, 7, 3]`
 `2`
 `3` `alert( Math.max.apply(Math, arr) ) ``// (*)`

Here, we call `Math.max`, passing array of arguments `args`.

In the “natural” call `Math.max(...)`, the context `this` is set to `Math`, the object before dot`'.'`. In our code we keep it same by explicitly passing to `apply`.

Actually, talking about `Math.max` – this method does not use the context at all. We could abuse that to simplify our code even further:

 `1` `var` `arr = [1, -2, 7, 3]`
 `2`
 `3` `alert( Math.max.apply(0, arr) ) ``// dummy '0' context`

## Keyword arguments

Imagine you’ve got a function with several arguments. And most of them will have default values.

Like the following:

 `1` `function` `showWarning(width, height, title, contents, showYesNo) {`
 `2` `  ``width = width || 200; ``// default values`
 `3` `  ``height = height || 100;`
 `4` `  `
 `5` `  ``var` `title = title || ``"Warning"``;`
 `6`
 `7` `  ``...`
 `8` `}`

Here we have a function to show a warning window. It allows to specify `width, height, title`, textual `contents` and show the button if `showYesNo` is set.

Most parameters have default values.

Here is how we use it:

 `showWarning(``null``, ``null``, ``null``, ``"Warning text"``, ``true``)`
 `// or`
 `showWarning(200, 300, ``null``, ``"Warning text"``)`

The problem is: people tend to forget arguments order, and what they mean.

Imagine you have 10 arguments and most are optional. The function call becomes really terrifying.

In JavaScript, it is implemented with a parameters object:

 `1` `function` `showWarning(options) {`
 `2` `  ``var` `width = options.width || 200  ``// defaults`
 `3` `  ``var` `height = options.height || 100`
 `4` `  `
 `5` `  ``var` `title = options.title || ``"Warning"`
 `6`
 `7` `  ``// ...`
 `8` `}`

Calling such function is easy. You just pass an object of arguments like this:

 `1` `showWarning({`
 `2` `  ``contents: ``"Text"``,`
 `3` `  ``showYesNo: ``true`
 `4` `})`

Another bonus is that the arguments object can be reconfigured and reused:

 `01` `var` `opts = {`
 `02` `  ``width: 400,`
 `03` `  ``height: 200,`
 `04` `  ``contents: ``"Text"``,`
 `05` `  ``showYesNo: ``true`
 `06` `}`
 `07`
 `08` `showWarning(opts)`
 `09`
 `10` `opts.contents = ``"Another text"`
 `11` `showWarning(opts) ``// another text with same options`

Keyword arguments are employed in most frameworks.

## Special `arguments` properties

### `arguments.callee`

There is an interesting property of `arguments`, namely `arguments.callee`. It references the function which is being run.

This property is deprecated by ECMA-262 in favor of named function expressions and for better performance.

JavaScript implementations can optimize the code much better if they know that keeping `arguments.callee` is not required.

It will trigger error in “strict mode”, which you need to enable. Normally, it works.

Usually it is used for recursion in anonymous functions.

For example, `setTimeout(func, ms)` is a built-in function which calls `func` after `ms` microseconds.

 `1` `setTimeout( `
 `2` `  ``function``() { alert(1) }, ``// alerts 1 after 1000 ms (=1 second)`
 `3` `  ``1000`
 `4` `)`

The function has no name. To call it recursively 3 times, let’s use `arguments.callee`:

 `1` `var` `i = 1`
 `2` `    setTimeout( `
 `3` `    ``function``() {`
 `4` `alert(i)`
 `5` `    ``if` `(i++<3) setTimeout(arguments.callee, 1000)`
 `6` `  ``},`
 `7` `  ``1000`
 `8` `)`

Another example is factorial:

 `1` `// factorial(n) = n*factorial(n-1)`
 `2` `var` `func = ``function``(n) { `
 `3` `  ``return` `n==1 ? 1 : n*arguments.callee(n-1) `
 `4` `}`

The factorial function given above works even if `func` is reassigned to something else. That’s because it uses `arguments.callee` to reference itself.

### `arguments.callee.caller`

The property arguments.callee.caller keeps the reference to a calling function.

This property is deprecated by ECMA-262, for the same reason as `arguments.caller`.

There is a property `arguments.caller` with same meaning, but less supported. Don’t use it, stick to `arguments.callee.caller`, all browsers have it.

In the example below, `arguments.callee.caller` references the calling function of `g`, that is `f`.

 `01` `f()`
 `02`
 `03` `function` `f() {`
 `04` `  ``alert(arguments.callee.caller) ``// undefined`
 `05` `  ``g()`
 `06` `}`
 `07`
 `08` `function` `g() {`
 `09` `  ``alert(arguments.callee.caller) ``// f`
 `10` `}`