on
07-May-2015
10:04
- edited on
05-Jun-2023
22:30
by
JimmyPackets
JavaScript, and thus Node.js, is at it's heart a functional programming language. Functions are fully typed objects that can be modified, extended, and used as data objects.
A function is a block of code designed to perform a specific task and is much the same as a procedure or subroutine in other programming languages. Node.js takes advantage quite extensively of this capability allowing the developer to define code once and reuse it many times.
A JavaScript function is defined with the "function" keyword, followed by a name, followed by parentheses. A function name has the same rules as variables in that they can contain letters, digits, underscores, and dollar signs. The code to be executed in the function is placed inside curly braces after the function declaration.
function name(param1, param2, ...) { code to be executed }
As I mentioned above, functions can be used as data objects in code and other function calls. When passing a function in as a parameter, one could do something like this
function passInFunc(f) { f("in myfunc"); } function myfunc(param) { console.log(param); } passInFunc(myfunc);
When control hits the "passInFunc" function, the name of the "myfunc" function is not relevant. this is where "Anonymous functions" come into play. Anonymous functions are commonly used as callback parameters when using the Event Emitter pattern described in my article on Node.js Events.
An anonymous function can be declared either as a standalone variable
function passInFunc(f) { f("in myfunc"); } var f = function(param) { console.log(param); } passInFunc(f);
or more concisely as
function passInFunc(f) { console.log("in myfunc"); } passInFunc(function(param) { console.log(param); });
It is this later format that you see used extensively in the Event Emitter pattern. Anonymous functions have the drawback in that when exceptions are thrown, the debugger does not have a name context for the call stack which makes life a bit more difficult when debugging.
To declare parameters, you simply list them in the parentheses separated by commas. Since JavaScript is a loosely typed language, there is no checking of these parameters at runtime. If a function is declared with two parameters, but the caller does not include them, the values of the parameters within the function will be set to undefined. Within the scope of the function, parameters have local scope to the function, meaning that their values are not accessible from a global scope or from other functions.
function func(param1, param2, param3) {} func("one"); // param2, and param3 are undefined func("one", "two"); // param3 is undefined func("one", "two", "three"); // all parameters are defined
Functions can include return statements. When a return statement is reached, the function will stop executing and control will be returned to the code after the statement that invoked the function call. To return a status back to the caller, the return statement can take an optional value parameter which the caller can use to make logic decisions.
function add(a, b) { return a+b; } var sum = add(1,2) // the sum variable will contain the value 3.
To cause the function to execute, you must include the () operator after the function name. Referencing just the function name refers to the function object.
function myfunc(param) { } # f contains the myfunc object var f = myfunc; # f contains the return value from the myfunc var f = myfunc(param);
When a function is called, a new variable scope is created. Variables declared in the calling scope are available to the function, but variables declared within the new function scope are not available when the function completes it's processing and returns.
var best_language = "JavaScript"; function print_best() { console.log(best_language); best_language = "c++"; console.log(best_language); } print_best(); console.log(best_language);
The above code will print the following to the console
JavaScript c++ JavaScript
Combining scope with anonymous functions can yield some interesting ways to do work with private variables that disappear when the anonymous function exits.