JavaScript Functions

Functions are objects in JavaScript and can be used as variables in expressions, passed to other functions, or treated like numbers or strings.

The traditional function declaration has several parts:

  • function keyword;
  • name of the function;
  • function body, which contains JavaScript statements; and
  • return statement

Functions may have "parameters", values passed to the function from a calling program, but they are not required. To execute a function, it must be "called". This will run the statements in the body of the function. Read this article about how functions are defined and used. After reading this article, consider these questions: 

  • What is the difference between local, global, and lexical scoping?
  • Can functions be called with different numbers of parameters?
  • What is returned if a function does not have a "return" statement?

Bindings and scopes

Each binding has a scope, which is the part of the program in which the binding is visible. For bindings defined outside of any function or block, the scope is the whole program - you can refer to such bindings wherever you want. These are called global.

But bindings created for function parameters or declared inside a function can be referenced only in that function, so they are known as local bindings. Every time the function is called, new instances of these bindings are created. This provides some isolation between functions - each function call acts in its own little world (its local environment) and can often be understood without knowing a lot about what's going on in the global environment.

Bindings declared with let and const are in fact local to the block that they are declared in, so if you create one of those inside of a loop, the code before and after the loop cannot "see" it. In pre-2015 JavaScript, only functions created new scopes, so old-style bindings, created with the var keyword, are visible throughout the whole function that they appear in - or throughout the global scope, if they are not in a function.

let x = 10;
if (true) {
  let y = 20;
  var z = 30;
  console.log(x + y + z);
  // → 60
}
// y is not visible here
console.log(x + z);
// → 40


Each scope can "look out" into the scope around it, so x is visible inside the block in the example. The exception is when multiple bindings have the same name - in that case, code can see only the innermost one. For example, when the code inside the halve function refers to n, it is seeing its own n, not the global n.

const halve = function(n) {
  return n / 2;
};

let n = 10;
console.log(halve(100));
// → 50
console.log(n);
// → 10