Why Do We Use Const to Declare Arrow Functions in JavaScript?

Why Do We Use Const to Declare Arrow Functions in JavaScript?


Why use const over let to declare functions in JavaScript?

  • Arrow functions declared with const cannot have their values changes/reassigned
    - Note: When you "declare" a function with let or const it is technically referred to as a function expression rather than a function declaration

  • The const syntax is very human readable
    - There is a clear intent to other developers on your team that you do not want your function to be manipulated

  • Const prevents accidental variable/function reassignment, a common mistake that plagues large codebases with several developers

In the following guide we will explore the differences between declaring functions using the function keyword, var, let, and const.


If you're like me, you're used to declaring functions using the function keyword because its arguably the easiest syntax to read. With the rising popularity of arrow functions, I decided to familiarize myself with their syntax so that I could better understand guides and other written material that contained them.

When I dove in I was immediately confused by the use of let and const and why we would use one over the other since they seem to function the same way.


/***
** Example Functions **
***/

//Function Declaration
function add(x, y) {
  return x + y;
}

//Arrow Function Expression w/ const
const add = (x, y) => {
  return x + y;
}

//Arrow Function Expression w/ let 
let add = (x, y) => {
  return x + y;
}

Arrow and Function Declarations in JavaScript

You may not be aware, but functions in JavaScript are a type of variable. This is important to know because it means that, like variables, their value can be manipulated. This presents a problem, typically in large codebases, where an accidental double use of a variable can result in a function's code being manipulated or completely wiped out.

Before ES6, variables were commonly declared with the var keyword and functions with the function keyword. Both these methods allowed for functions to be accidentally manipulated. When ES6 came out, we were introduced to new ways of declaring variables, namely the keywords let and const.

Here's an example of a function being accidentally overwritten by some text when using var and function:


// Creating the addOne function that returns the value of x + 1
var addOne = function(x) {
  return x + 1;
}
console.log(addOne(5)); // 6

// Declaring a variable with the same name as the function above
var addOne = "test";

console.log(addOne); // test
console.log(addOne(5)); // Error: addOne is not a function

Declaring Arrow Functions with Const

When you declare a variable in JavaScript using const you're declaring it as a constant. Constant variables are read-only meaning they cannot be overwritten or modified. This same principle is applied to arrow functions declared with a const, they cannot be modified or overwritten, protecting the code inside from accidental deletion or manipulation.

It's important to note that when we say "declare" a function using const, its properly referred to as a function expression and not a function declaration.


const add = (x, y) => {return x + y;}

By "declaring" our function this way we ensure that is it a constant reference that you can trust hasn't been manipulated from its original form. Any attempt to modify our function will result in an error. This is important for codebase stability and reliability, especially as the codebase and development team grow.

Below is an example of creating a function expression with const followed by "accidentally" trying to reassign it's value, resulting an error - preventing an unintended result from the function:


// Function expression with const
const add = (x, y) => {return x + y;}

add = (x, y) => {return x - y;} //Error: Cannot assign this new value to a constant variable

Declaring Arrow Functions with Let

When you declare a variable in JavaScript using let you're declaring your variable in such a way that its value can be changed. Similar to the var and function example above, this can be problematic in larger code bases where a developer may unknowingly manipulate how a function works producing unintended consequences such as errors.

Just like with const, when we "declare" a function using let, we're creating what's referred to as a function expression and not a function declaration.


// Message of the day (motd) function expression
let motd = (time) => {return "Good Morning";};

console.log(motd()); // Good Morning

However, sometimes the ability to reassign the value of a function is intended, you can see a basic message of the day function example below, where a time variable manipulates the message that will be displayed in the console:


// Message of the day (motd) function expression
let motd = (time) => {return "Good Morning";};

// Define a variable that will be used to manipulate how the motd function works
let time = "afternoon";

// If the value of time is "afternoon" then change how the motd function works
if (time == "afternoon") {
  motd = (time) => {return "Good Afternoon";}
}

console.log(motd()); // Good Afternoon

Hoisting functions with var, let, and const

Hoisting often seems to come up as a possible reason why we would choose between let and const when creating functions. Hoisting in JavaScript speaks to the ability to call and use variables before they've been declared in the code. This is because variables declared with var, let, and const are hoisted to the top of their current block scope, or containing function.

However, hoisting is rarely, if ever, the driving factor in choosing how to declare your functions. As mentioned above when we use var, let, or const in creating our functions, we are creating a function expression and not a function declaration. All function expressions are not hoisted no matter what type of variable you choose.

If you're interested in learning more about hoisting in JavaScript, you can read more about it here.