JavaScript functions
Table of Contents
Function Expression
A function expression starts with the keyword function followed by the function arguments in parentheses and the function body in curly braces:
const square = function(x) {
return x * x;
};
console.log(square(4)); // >> 16
Function Scope
- Each function defines a scope
- Local variables of a function are not visible outside of the function
const a = "Hello "; // a has global scope
const f = function(b) { // b is local to f
const c = "!"; // c is local to f
console.log(a+b+c);
};
f("World"); // >> Hello World!
console.log(typeof b); // >> undefined
console.log(typeof c); // >> undefined
Lexical Scope
Variables have lexical (static) scope, i.e., the scope of a variable is determined by the code context of the variable:
const a = 2;
const f = function(b) {
return a+b;
};
console.log(f(7)); // >> 9
const g = function() {
const a = 5; // a is hiding the global variable inside g
return f(7); // but the global variable is used inside f
};
console.log(g()); // >> 9
Nested Scope
- Blocks and functions can be created inside other blocks and functions
- Each local scope can access the variables from the surrounding scopes
const a = 2;
const f = function(b) {
let x = 1;
const g = function() { // g has access to the local variables of f and to
x *= a; // the variables of the global scope
};
while (x < b) g();
return x;
};
console.log(f(100)) // >> 128
Functions are Objects
Functions are objects, hence they can be used as arguments and return values of other functions (higher-order functions)
// Function as argument
const repeat = function(action, n) {
for (let i = 0; i < n; i++) action();
};
const sayHello = function() {
console.log("Hello");
}
repeat(sayHello, 3); // >> Hello Hello Hello
// Function as return value
const formatter = function(prefix, suffix) {
return function(s) {
return prefix+s+suffix;
}
};
const format = formatter("'", "!'");
console.log(format("Hello World")); // >> 'Hello World!'
Closure
A function that references a specific instance of a local variable in an enclosing function is called a closure:
const counter = function(init) {
let val = Number(init);
return function() {
return ++val;
};
};
const countA = counter(12); // countA references a specific instance of val
console.log(countA()); // >> 13
console.log(countA()); // >> 14
const countB = counter("6"); // countB references another instance of val
console.log(countB()); // >> 7
console.log(countA()); // >> 15
Function Declaration
A function declaration defines a variable which points to the given function:
// Declare f to be a function
function f() {
return "I'm a chicken";
}
console.log(f()); // >> I'm a chicken
// The variable f can be reassigned
f = function() {
return "I'm a fox";
}
console.log(f()); // >> I'm a fox
Function Declarations are Hoisted
Function declarations are not part of the regular top-to-bottom flow of control:
// The function f can be used before it is declared
console.log(f(4)); // >> 48
function f(a) {
return g() * a;
};
function g() {
return 12;
}