Functions in JavaScript are special built-in objects. Because their purpose is to interact with web components, they have properties and usages that are unique and different from common programming languages like Java/C++. There are different ways of coding JavaScript functions.

Let’s start with something familiar though. Regular functions are declared with a function statement, and they are later called by name like standard functions in other common languages . They are useful when you want to group lines of code that have a single responsibility.

function multiply() {
    var result = 3 * 4
    console.log("3 multiplied by 4 is ", result)
}
multiply();
3 multiplied by 4 is  12

Functions can return objects. This second version of the multiply function returns the result of input paremeters a*b, which is then stored in myvar.

function multiply2(a, b) {
    return a*b
}
var myvar = multiply2(5, 6)
console.log("multipy2(5, 6) returns " + myvar)
multipy2(5, 6) returns 30

Immediately Invoked Function Expressions run as soon as the browser comes across it during load. A common way to code these functions is to wrap with parenthesis, followed by ().

Sometimes you will see a “defensive semicolon” infront of the immediately invoked function to guard against issues when concatentating two script sources together. This prevents issues when blindly concatenating two files. Since JavaScript doesn’t require semicolons, you might concatenate with a file with some statements in its last line that causes a syntax error.

var x = "This x is global and can be accessed in the function";

(function(p) {
    var result = 12 / 0.75
    console.log("12 divided by 0.75 is ", result)
    console.log(p)
    console.log(x)
})("This string is passed into function's p variable")

;(function() {
    console.log("This immediately invoked function has a defensive semicolon")
})()
12 divided by 0.75 is  16
This string is passed into function's p variable
This x is global and can be accessed in the function
This immediately invoked function has a defensive semicolon

Anonymous functions are created such that they have no canonical name, and so can’t be invoked with a standardized function name, but they can be declared and stored into an object variable. The function is invoked by calling the variable as if it were the function’s name.

var result = 100
var divided = function() {
    var result = 3 / 4
    console.log("3 divided by 4 is ", result)
    return result
}
var whatIsThis = divided()
console.log("the anonymous function's `result` variable is " + whatIsThis)
3 divided by 4 is  0.75
the anonymous function's `result` variable is 0.75

Function objects

Every JavaScript function is actually a Function object. This can be seen by testing the constructor type

(function(){}).constructor === Function
true

Function objects have a name property.

function foo() {
    console.log("Guess what my name is...");
}

foo()
console.log(foo.name)
Guess what my name is...
foo

Anonymous function expressions that were created using the keyword function or arrow functions would have "" (an empty string) as their name.

(function() {}).name; // ""
(() => {}).name; // ""
''

Closures and functions

A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function’s scope from an inner function. In JavaScript, closures are created every time a function is created, at function creation time.

One common use for anonymous functions are creating closures–the function’s environment consists of any local variables that were in-scope at the time the closure was created. In the example below, the function is working with local and contained in the scope of the function.

createFunction1() constructs a Function object (and returns the Function object). Functions created with the Function constructor do not create closures to their creation contexts; they always are created in the global scope. When running them, they will only be able to access their own local variables and global ones, not the ones from the scope in which the Function constructor was created.

The createFunction2() function is an inner function f() that is defined inside init() and is available only within the body of the init() function. Note that the f() function has no local variables of its own. However, since inner functions have access to the variables of outer functions, f() can access the variable name declared in the parent function, createFunction2().

var q = 10;

function createFunction1() {
    var q = 20;
    console.log("Using Function constructor to create function won't know about local q in createFunction1...");
    return new Function('return q;'); // this |q| will refer to global |q|
}

function createFunction2() {
    var q = 20;
    console.log("Declaring an inner function that has access to local q in createFunction2...")
    function f() {
        return q; // this |q| refers local |q| right above
    }
    return f;
}

var f1 = createFunction1();
console.log(f1());          // prints global q=10
var f2 = createFunction2();
console.log(f2());          // prints local q=20
q = 42; //update global q
console.log(f1()); // prints global q=42
console.log(f2());    // prints local q=20
Using Function constructor to create function won't know about local q in createFunction1...
10
Declaring an inner function that has access to local q in createFunction2...
20
42
20