2.2 Function declarations vs. function expressions

The book Structure and Interpretation of Computer Programs published in 1985 and written by Gerald Jay Sussman expressed that some languages treat functions as “first class citizens”:

The language supports passing functions as arguments to other functions, returning them as the values from other functions, and assigning them to variables or storing them in data structures. TypeScript is one of the languages that treats functions as first class citizens. In this recipe, we will learn about some peculiarities of the behavior of function declarations and functions expressions.

Getting Ready

The only prerequisite is that you should be able to use function declarations and function expressions is an installation of TypeScript 2.0 or higher.

How to do it…

We can declare a function as a named function using a function declaration:

function saySomethingNamed() { 
  return 'Something!'; 
}

We can also declare a function as an unnamed function using a function expression:

const saySomethingUnnamed = function() { 
  return 'Something!'; 
}

Notice how the second function was assigned as the value of a variable named saySomethingUnamed but the function itself is unnamed, you can check it by accessing the name property which is available in all the function objects.

saySomethingNamed.name === 'saySomethingNamed'; // true
saySomethingUnnamed.name === '';             	 // true

TypeScript allows us to to assign an unnamed function to a variable named saySomethingUnnamed because functions are treated as first class citizens.

How it works…

We have learned that function expressions allow us to declare anonymous function but there are other significant differences between function declarations and function expressions. If we invoke the previously declared functions, we may think that the two functions will always behave in a really similar way:

function saySomethingNamed() { 
  return 'Something!'; 
} 
const saySomethingUnnamed = function() { 
  return 'Something!'; 
}

console.log(saySomethingNamed());   // "Something!"
console.log(saySomethingUnnamed()); // "Something!"

However, if we change the order of the function declarations and function invocations we will get runtime error:

console.log(saySomethingNamed());   // "Something!" 
console.log(saySomethingUnnamed()); // Error

function saySomethingNamed() { 
  return 'Something!'; 
} 

const saySomethingUnnamed = function() { 
  return 'Something!'; 
}

This error is thrown because function declarations and function expressions are evaluated in different points in time. Function declarations are evaluated before the program is executed so when we try to invoke the saySomethingNamed function it has been already evaluated. In the case of the function expression, the assignment must be completed before the function can be evaluated.

Source Code

Function declarations vs. function expressions


Shiv Kushwaha

Author/Programmer