For repetitive code, you can introduce a function. For example:
js> function max(num1, num2) {
> return num1 > num2 ? num1 : num2;
> }
js> max(10, 5);
10
js>
> return num1 > num2 ? num1 : num2;
> }
js> max(10, 5);
10
js>
The above example demonstrates the basic way to declare and call a function. A function is defined using the function keyword followed by a name. The function parameters are placed in the parenthesis (). The return keyword is used to return a result from a function. If you don't return anything, it will return undefined.
Function parameters are just named variables. In fact, the number of arguments can be less than the number of parameters. If fewer arguments are passed into a function, the default value of the unspecified parameters is undefined.
js> function func(a, b) {
> print(a);
> print(b);
> }
js> func(10, 20);
10
20
js> func(10);
10
undefined
js> func();
undefined
undefined
js> func(10, 20, 30, 40);
10
20
js>
> print(a);
> print(b);
> }
js> func(10, 20);
10
20
js> func(10);
10
undefined
js> func();
undefined
undefined
js> func(10, 20, 30, 40);
10
20
js>
In the above example, you can see that it's also workable to pass more arguments than parameters. Where are those exceeding arguments? In fact, a variable arguments is declared automatically in the function and refers to an array-like object. It holds all arguments while calling a function. For example, you can define a function to sum up a list of numbers as follows:
js> function sum() {
> var sum = 0;
> for(var i = 0; i < arguments.length; i++) {
> sum += arguments[i];
> }
> return sum;
> }
js> sum(1, 2);
3
js> sum(1, 2, 3);
6
js> sum(1, 2, 3, 4);
10
js>
> var sum = 0;
> for(var i = 0; i < arguments.length; i++) {
> sum += arguments[i];
> }
> return sum;
> }
js> sum(1, 2);
3
js> sum(1, 2, 3);
6
js> sum(1, 2, 3, 4);
10
js>
The arguments object is not an Array instance. It's an object with numeric properties and each property stores an argument respectively. It also has a length property to represent the number of arguments.
In JavaScript, parameters are just named variables. As a matter of fact, if you change a parameter value, the arguments object also reflects the value of the corresponding index.
js> function func(a, b) {
> print(a + ': ' + arguments[0]);
> print(b + ': ' + arguments[1]);
> a = 0;
> b = 0;
> print(a + ': ' + arguments[0]);
> print(b + ': ' + arguments[1]);
> }
js> func(100, 200);
100: 100
200: 200
0: 0
0: 0
js>
> print(a + ': ' + arguments[0]);
> print(b + ': ' + arguments[1]);
> a = 0;
> b = 0;
> print(a + ': ' + arguments[0]);
> print(b + ': ' + arguments[1]);
> }
js> func(100, 200);
100: 100
200: 200
0: 0
0: 0
js>
The number of arguments doesn’t need to equals that of parameters while calling a function. If you want to confirm the numbers of arguments and parameters are equivalent, you can check the length property of arguments. For example:
js> function func(a, b) {
> if(arguments.length != 2) {
> throw new Error('must give 2 arguments');
> }
> }
js> func(10);
js: "<stdin>", line 40: exception from uncaught JavaScript throw: Error: must give 2 arguments
at <stdin>:40 (func)
at <stdin>:39
js> func(10, 20);
js>
> if(arguments.length != 2) {
> throw new Error('must give 2 arguments');
> }
> }
js> func(10);
js: "<stdin>", line 40: exception from uncaught JavaScript throw: Error: must give 2 arguments
at <stdin>:40 (func)
at <stdin>:39
js> func(10, 20);
js>
However it's not JavaScript's convention to check the number of arguments. The convention is to provide default values while arguments are in short supply. That's easy to do. If there is a shortage of arguments, redundant parameters will be undefined. The undefined will be treated as false in a conditional statement or expression so you can provide default values as follows:
js> function numberGenerator(length, begin, step) {
> begin = begin || 0;
> step = step || 1;
> var numbers = [begin];
> length--;
> for(var i = 0; i < length; i++) {
> numbers.push(numbers[i] + step);
> }
> return numbers;
> }
js> numberGenerator(10);
0,1,2,3,4,5,6,7,8,9
js> numberGenerator(10, 5);
5,6,7,8,9,10,11,12,13,14
js> numberGenerator(10, 5, 2);
5,7,9,11,13,15,17,19,21,23
js>
> begin = begin || 0;
> step = step || 1;
> var numbers = [begin];
> length--;
> for(var i = 0; i < length; i++) {
> numbers.push(numbers[i] + step);
> }
> return numbers;
> }
js> numberGenerator(10);
0,1,2,3,4,5,6,7,8,9
js> numberGenerator(10, 5);
5,6,7,8,9,10,11,12,13,14
js> numberGenerator(10, 5, 2);
5,7,9,11,13,15,17,19,21,23
js>
The numberGenerator plays a number generator and the parameter length is indispensable. If you don't provide the parameter begin a value, the default value will be 0. Similarly, the default value of step is 1.
If there are too many options while calling a function, you can also pass it a option object. For example:
js> function func(option) {
> option = {
> x : option.x || 10,
> y : option.y || 20,
> z : option.z || 30
> };
> print(option.x);
> print(option.y);
> print(option.z);
> }
js> func({ x : 100 });
100
20
30
js> func({ x : 100, y : 200 });
100
200
30
js> func({ x : 100, y : 200, z : 300 });
100
200
300
js>
> option = {
> x : option.x || 10,
> y : option.y || 20,
> z : option.z || 30
> };
> print(option.x);
> print(option.y);
> print(option.z);
> }
js> func({ x : 100 });
100
20
30
js> func({ x : 100, y : 200 });
100
200
30
js> func({ x : 100, y : 200, z : 300 });
100
200
300
js>
In the above example, you should provide a option object when calling func. Properties of the option object provide necessary values for func. In the function, a default value will be setup if there's no corresponding property on the option object.