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.

No Comments