JavaScript Function Expressions

There are two different ways of creating functions in JavaScript. We can use function declaration and function expression. The difference between them is the function name, which can be omitted in function expressions to create anonymous functions.

Here is the syntax for Function Declaration:

function welcome() {
  console.log("Welcome to W3Docs!");
}
welcome();

And this is the syntax for Function Expression:

let welcome = function () {
  console.log("Welcome to W3Docs!");
};
welcome();

The function is assigned to the variable, like any other value. No matter how the function is defined, because it is just a value stored in the variable welcome.

We can also show that value using console.log:

function welcome() {
  console.log("Welcome to W3Docs");
}
console.log(welcome); // it shows code of the function
welcome();
The last line does not run the function, as there are no parentheses after welcome.

JavaScript is not like the programming languages where any mention of a function name causes its execution. In JavaScript, a function is a value and we can deal with it as a value. The code in the example above shows its string representation, which is the source code.

A function is a special value, we can call it like welcome(). It is still a value and we can work with it the way we work with other values.

We can even copy a function to another variable like this:

function welcome() { // (1) create the function
  console.log("Welcome to W3Docs");
}
let anotherFunc = welcome; // (2) copy 
anotherFunc(); // Welcome to W3Docs  //it works
welcome(); // Welcome to W3Docs    // this works too

Let’s discuss what happens above in detail:

  1. The Function Declaration (1) creates the function putting it into the variable named welcome.
  2. Line (2) copies the variable welcome into the variable anotherFunc.
  3. It is possible to call the function as both welcome() and anotherFunc().
If we have used a Function Expression to declare welcome, in the first line nothing would change:
let welcome = function () {
  console.log("Welcome to W3Docs");
};
let anotherFunc = welcome;
anotherFunc();

A semicolon at the end

You can ask, why does Function Expression have a semicolon ; at the end, but Function Declaration does not:

function welcome() {
  // ...
}
let welcome = function () {
  // ...
};

The reason is there’s no need for ; at the end of code blocks and syntax structures that use them as if { ... }, for { }, function f { } and so on.

A Function Expression can be used inside the statement: let welcpme = ...;, as a value, but not a code block. It is recommended to put the semicolon ; at the end of statements, no matter what the value is. That is why the semicolon here is not related to the Function Expression itself.

Callback functions

A function passed to another function is called a “callback” in JavaScript.

There are examples of passing functions as values and using function expressions presented below.

The function should ask the siteQuestion and call answerYes() or answerNo() depending on the user’s answer:

function callbackFunc(siteQuestion, answerYes, answerNo) {
  if (confirm(siteQuestion)) {
    answerYes() 
  } else { 
    answerNo();
  }
}
function chooseOk() {
  console.log("It’s great.");
}
function chooseCancel() {
  console.log("Try again");
}
// use answerOk, answerCancel functions passed as arguments to the request
callbackFunc("Are you familiar with JS function decalarations?", chooseOk, chooseCancel);

In practice, this kind of functions are quite useful. The main difference between a real-life callbackFunc and the example above is that real-life functions use more difficult ways to interact with the user than a simple confirm.

We call the arguments chooseOk and chooseCancel of ask callback functions or callbacks.

We pass a function expecting that it will be “called back” later if necessary. In this case, chooseOk becomes the callback for “yes” answer, and chooseCancel for “no”.

We can use Function Expressions if we want to write the same function much shorter:

function callbackFunc(siteQuestion, answerYes, answerNo) {
  if (confirm(siteQuestion)) {
    answerYes();
  } else {
    answerNo();
  }
}
callbackFunc(
  "Are you familiar with JS function decalarations?",
  function () {
    console.log("It’s great.");
  },
  function () {
    console.log("Try again");
  }
);

Functions are declared inside the callbackFunc(...) call and they have no name, that is why they are called anonymous. this kind of functions are not accessible outside of callbackFunc. This kind of code appears in our scripts very naturally.

A function is a value that represents an “action”.

Structured values like strings or numbers represent the data. A function can be considered as an action. We can proceed it between variables and run when we want.

Function Expression and Function Declaration

The main differences between Function Declarations and Expressions is the syntax.

Function Expression defines a function, created inside an expression or another syntax construct. The presented function is created at the right side of the “assignment expression” =

// Function Expression
let sum = function (a, b) {
  return a + b;
};

A Function Expression works almost the same way as a function declaration or a function statement, the only difference is that a function name is not started in a function expression. The function expressions run as soon as they are defined.

Function Declaration defines a named function, declared as a separate statement, in the main code flow. Just as Variable Declaration must start with “var”, Function Declaration must start with “function”.

// Function Declaration
function sum(a, b) {
  return a + b;
}

The more delicate difference between the functions is when a function is created by the JavaScript engine.

A Function Expression is created when the implementation reaches it and can be used only from that moment.

Once the execution flow passes to the right side of the assignment let sum = function..., the function is created and can be used.

Function Declarations are different.

Function Declarations can be called earlier than they are defined. For instance, no matter where a global Function Declaration is, it is visible in the whole script. The reason is internal algorithm.

When all Function Declarations are processed, the code is executed and has access to these functions.

For instance, this works:

welcome("W3Docs"); // Welcome to W3Docs
function welcome(siteName) {
  console.log(`Welcome to, ${siteName}`);
}

But it would not work If it was a Function Expression:

welcome("W3Docs"); // error!
let welcome = function (siteName) { // (*) there is no more magic
  console.log(`Welcome to  ${siteName}`);
};

Function Expressions will be created when the implementation reaches them, what would happen only in the line (*).

One more special attribute of Declaration is its block scope.

When a Function Declaration is in a code block in strict mode, it will be visible everywhere inside that block, but not outside of it.

For example, let’s suppose that we need to declare a function welcome() depending on the age variable that we get during runtime, then we plan to use it later.

If we use Function Declaration in strict mode, it won’t work as planned:

"use strict"
let number = prompt("Guess the number", "");
// conditionally declare a function
if (number == 10) {
  function guessNumber() { // A function declaration is available everywhere 
    console.log("it’s right!"); //in the block where it is declared.
  }
} else {
  function guessNumber() {
    console.log("it’s wrong!");
  }
}
//we cannot see function declarations inside them, 
//because here we have left the braces
guessNumber(); // Error: guessNumber is not defined

What can we do for making welcome visible outside of if?

The best proposal would be to use a Function Expression and assign welcome to the variable that is declared outside of if.

This code works as planned:

"use strict"
let number = prompt("Guess the number", "");
let guessNumber;
// conditionally declare a function
if (number == 10) {
  guessNumber = function () {
    console.log("it’s right!");
  }
} else {
  guessNumber = function () {
    console.log("it’s wrong!");
  }
}
guessNumber(); // now it’s work

But we could also simplify it using a question mark operator ?:

let number = prompt("Guess the number", "");
let guessNumber = (number == 10) ?
  function () {
    console.log("it’s right!"); 
  }  :
  function () {
    console.log("it’s wrong!");
  };
guessNumber();  // it’s work

When to choose Function Declaration against Function Expression?

When we need to declare a function, Function Declaration syntax is the first to consider. With it we are free to organize our code the way we want, because we can call such functions before they are declared.

One more advantage is readability, as it’s easier to look up function f(…) {…} in the code than let f = function(…) {…};. Function Declarations are more impressive. But we need to use Function Declaration in case we need a conditional declaration.




Do you find this helpful?

Related articles