JavaScript ES6 - Var, Let And Const

Introduction and Background

 
Most developers who are new to the JavaScript language tend to end up writing error-prone JavaScript programs (just like me!). One probable reason is because of the belief that JavaScript variables are block-scoped. Until they realized it isn't, which results in a harder-to-read debugging nightmare. I've been there and I hate that feeling but it was a great learning experience. 
 
In this blog post, we are going to discuss the following keywords: var, let and const. You might be thinking: I already know var, let's get straight to let and const. To give a bit more background to our reader, we will be including the var keyword to see the reason behind why let and const was added to the language. Ok, let's get started then.
 

The var keyword

 
Basically, when JavaScript reads your code all variable declarations using var are lifted to the top of local scope (if declared inside a function) or to the top of the global scope (if declared outside of a function) regardless of where the actual declaration has been made.
 
JavaScript scope
  1. Local - variable declared within a JavaScript function, becomes local to the function and can be accessed only within the function. 
  2. Global - variable declared outside a function, becomes global.
Just remember, that JavaScript variables that are declared using the var keyword are called function scoped. It is accessible globally to the script if declared outside the function. Similarly, with the function scoped variables that are declared inside a function, then they become accessible throughout the function, but not outside the function. 
 
Let us see this in action. 
  1. myVariable = 10;  
  2.   
  3. console.log(myVariable); //output 10  
  4.   
  5. var myVariable;  
If you are going to try the example above it will output the number 10. Now, as you can see a variable can be declared after it has been used. It's kinda weird actually. But that's how JavaScript works. 
Now, let see another example. 
  1. var outsideFunction = 100; //accessible globally  
  2.   
  3. function myFunction(){  
  4.   
  5.     console.log(outsideFunction);  
  6.   
  7.     var variableInsideFunc = 10; //accessible throughout the function  
  8.   
  9.     if(true){  
  10.         var variableIfBlock = 12; //accessible throughout the function  
  11.         console.log(variableInsideFunc);  
  12.     }  
  13.   
  14.     console.log(variableIfBlock); //outputs 12;  
  15. }  
  16.   
  17. myFunction();  
In the example above, you can see that the variableIfBlock variable is accessible outside the if statement. Now, if you are coming from a different language you wouldn't expect that to happen, right? Or probably, you'd expect something like an error or undefined. But, that's not the case when using the var keyword. 
 

The let keyword

 
Variables that are declared using the let keyword are called block-scoped variables.
 
It actually behaves the same way as function scoped variables when declared outside a function, that is, they are accessible globally.
 
However, when the blocked scoped variables are declared inside a block, they are accessible inside the block that they are defined in (and also any sub-blocks) but not outside the block. 
 
Let's see this in action. 
  1. let variableUsingLet = 12;   
  2.   
  3. function myFunctionWithLet(){  
  4.     console.log(variableUsingLet);  
  5.   
  6.     let variableInsideFuncUsingLet =10; //accessible throughtout the function block  
  7.   
  8.     if(true){  
  9.         let variableIfBlockUsingLet = 12; //accessible throughout the "if" block  
  10.         console.log(variableInsideFuncUsingLet);  
  11.     }  
  12.   
  13.     console.log(variableIfBlockUsingLet);  
  14. }  
  15.   
  16. myFunctionWithLet();  
  17.   
  18. /** 
  19.     output 
  20.     12 
  21.     10 
  22.     'Reference Error' 
  23. */  
Now, the output is what we are talking about in blocked-scope. Or let's just say if you are coming from another language this is what you are expecting. Again, as you can see when we tried to access the variableIfBlockUsingLet outside the if block a Reference Error exception has been thrown. 
 
Another good thing to mention about the var and let keyword is that they behave differently when it comes to declarations of the variables. 
 
Let us see this in action below. 
  1. var firstVariable_1 = "hello";  
  2. var firstVariable_1 = "hello again";  
  3.   
  4. console.log(firstVariable_1); //output => hello again   
  5.   
  6. function myFunctionAgain(){  
  7.   
  8.     var functionVar = "myFunction";  
  9.     var functionVar = "myFunction2";  
  10.   
  11.     console.log(functionVar); //output => myFunction2  
  12. }  
  13.   
  14.  myFunctionAgain();  
  15.   
  16.  /** 
  17.   * Output 
  18.   * hello again 
  19.   * myFunction2 
  20.   */  
Basically, when using the var keyword it just overrides the values when redeclared.
 
Now, let's see what's the behavior when using the let keyword. 
  1. let firstVariable_1 = "hello";  
  2.   
  3. //Error: Uncaught SyntaxError: Identifier 'firstVariable_1' has already been declared  
  4. let firstVariable_1 = "hello again";   
  5.   
  6. function myFunctionAgain(){  
  7.   
  8.     let functionVar = "myFunction";  
  9.   
  10.      //Error: Uncaught SyntaxError: Identifier 'functionVar' has already been declared  
  11.     let functionVar = "myFunction2";  
  12. }  
  13.   
  14.  myFunctionAgain();  
  15.   
  16.    
When using the let keyword, it basically throws an error. It doesn't give you the opportunity to redeclare the variable which is acceptable to many developers.
 

Why not remove the var keyword and use the let keyword as the de facto standard?  

 
To answer this question, it's pretty easy because of backward compatibility. However; when writing the ES6 code, it is highly recommended to practice the usage of the let keyword instead of the var keyword because it prevents scoping mistakes, prevents accidental bugs that happened to me most the time and make code easier to read.
 

The const keyword

 
Using the const keyword declares a read-only variable that can't be reassigned. Now, to give you background. Before ES6, JavaSript developers usually prefix the variables that were supposed to be constant. See the example below. 
  1. var const_PI = 3.141;  
  2.   
  3. function distanceWalked(circumferenceInMeters){  
  4.   
  5.     return Math.floor(const_PI * circumferenceInMeters);  
  6. }  
  7.   
  8. console.log(distanceWalked(1000));  
Based on the sample code above, we believe that PI should remain constant at all times in any case. However; there is still a chance to accidentally change its value somewhere else in the program. Prefixing isn't enough to keep track of the constant variables especially in a huge web application. 
 
Thus, the const keyword comes to the rescue. It is introduced to provide native protection to the constant variables. So we can convert the previous example using the const keyword. 
  1. const PI = 3.141;  
  2.   
  3. function distanceWalked(circumferenceInMeters){  
  4.   
  5.     return Math.floor(PI * circumferenceInMeters);  
  6. }  
  7.   
  8. console.log(distanceWalked(1000));  
  9. PI = 3.141 +2; //Uncaught TypeError: Assignment to constant variable.  
Constant variables are also block-scoped variables, just like the let variables. Therefore; both of these keywords follow the same scoping rules.
Before ending this blog, I'll be showing one more example. See it below. 
  1. const customer = {  
  2.     firstName: "Jin",  
  3.     lastName: "Necesario"  
  4. };  
  5.   
  6. console.log(customer.firstName);  
  7.   
  8. customer.firstName = "Jin Vincent";  
  9.   
  10. console.log(customer.firstName);  
  11.   
  12. customer = { firstName: "Jo Mariecris", lastName: "Necesario" }; //Error thrown  
  13.   
  14. /** 
  15.  * Output  
  16.  * Jin  
  17.  * Jin Vincent 
  18.  * Uncaught TypeError: Assignment to constant variable 
  19.  */  
The example above shows that when assigning an object to a constant variable, the reference of the object becomes constant to the variable and not to the object itself. Thus, the object is mutable (can be changed). 
 
To explain a bit further, the variable customer stores the address (that is the reference pointer) of the object. Therefore, the address of the object is the value of the variable, and it cannot be changed. However; the object is mutable, changing the properties of the object was accepted.
 
However; when we tried to assign another object to the variable customer, an exception has been thrown.
 

Summary

 
In this blog post, we have discussed the var, let and const keywords. Not only that but we have shown the difference between those three when it comes to usage. I hope you have enjoyed this blog post, as I have enjoyed writing and coding the examples. Until next time, happy programming.