JavaScript Functions
When coming from a strongly-typed, object-oriented background, there may be some surprising elements when looking at how functions are used in JavaScript.
Functions in JavaScript don’t have any real concept of a
signature, like they would in .NET. All functions return a
value (which will be the value
undefined
if nothing is explicitly returned), so there are no void
functions, and, while you can define named parameters for a
function, callers of the function can provide more or less
parameters than specified. If less parameters are provided,
the other parameters will be
undefined, if more are provided, they are accessible via an implicit
array-like variable named
arguments. This also means that it’s not possible to have function
overloads which have the same name and differ just by
signature.
There are also two different ways to create a function. The one that looks more like the object-oriented style is a function statement. This is a statement that starts with function, then gives the function name, parameter list, and body. One special characteristic of function statements is that they are defined throughout the entire scope of their containing function (i.e. they can be used before they are defined). They are said to be hoisted to the top of the containing function.
The other option is a function expression. This can look just like a function statement, but doesn’t require a function name, and is a value that can be assigned to a variable, passed to another function, or invoked. Let’s see some examples:
var myFunc = function (x) {
if (typeof x === 'undefined') {
return 'no args';
} else if (typeof x === 'function') {
return x();
} else if (arguments.length === 1) {
return 'x was ' + x;
} else {
return arguments.length - 1 + ' extra arguments provided';
}
},
result1 = myFunc(),
result2 = myFunc(function (y) { console.log(y); }),
result3 = myFunc(statement),
result4 = myFunc(1),
result5 = myFunc({}, true, 'text');
console.log(result1, result2, result3, result4, result5);
function statement(x, y, z) {
console.log(x, y, z);
}
So, we start here by defining a variable
myFunc, whose value is a function expression. The function has
one parameter,
x, and
returns a string value indicating what was passed in. For
result1, we call
myFunc
without any arguments, and see that
x is
undefined. For
result2
and
result3, we call
myFunc
with a function argument (for
result2
it’s a function expression, for
result3
it’s a reference to a function defined via a function
statement), call that function, and return the result.
Because both functions we pass in don’t return anything, the
result is
undefined. Note that in
result3, we were able to use statement before it was defined. For
result4, we call
myFunc
with one argument, and refer to the value via the parameter
x.
For
result5, we call
myFunc
with more than one argument, and refer to the
arguments
collection.