6 Must Known New Features in ES6 – Part 1: Let & Const

UI5

These are the newest and most crucial features in ES6 or also known as ECMAScript 6, ES2015, or JavaScript 6. This series of articles explains them super simple for you. Plus, each article states how to use the specific feature at its best.

This is article 1 of the series. It is about let and const. Two new ways to declare a variable.

Var, let, and const

var used to be the only keyword in JavaScript to declare a variable:

var sVariable = “I’m a var declared variable.”;.

let and const are the two new keywords to declare a variable:

let sVariable = “I’m a variable declared by let.”;.

const sVariable = “I’m a variable declared by const.”;.

But what are the differences between var, let, and const and what declaration is to choose for what situation?

Hoisting

In order to understand the differences between var, let, and const, it is a prerequisite to know what Hoisting is in JavaScript.

Hoisting means that JavaScript puts behind the scenes the declarations of all your variables to the top of the scopes.

And a variable delaration is var bVariable;, let bVariable;, or const bVariable;. A variable initialization is bVariable = true;. Hence a variable declaration and initialization is var bVariable = true;, let bVariable = true, or const bVariable = true.

The scope of a variable is the space around a variable from which you are able to access the variable. For example, to access a variable to initialize this variable with a new value like bVariable = false;.

Two scopes exist: the global scope and the local scope.

Global scope: A variable is in the global scope if you declare it not in a function. A variable in the global scope is accessible from everywhere.

Local  scope: A variable is in a local scope if you declare it in a function. A variable in the local scope is to access only from within the function.

And there is one global scope. But there can be multiple local scopes.

// global scope 
var sVariable1 = "I'm in the global scope."; 

console.log(sVariable1); // returns I'm in the global scope. 

// local scope 
function myFunction { // here starts the local scope    
  
  var sVariable2 = "I'm in the local scope of myFunction."; 
  
  console.log(sVariable2); // returns I'm in the local scope of myFunction. 

} // here ends the local scope console.log(sVariable2); // returns null

Therefore, if your JavaScript file looks like this …

function fnFuntion(bVariable1) { // scope starts   

  if (bVariable1) {     

    var bVariable2 = true; // declare and initialize variable          

    console.log(bVariable1);   
  
  } 

} // scope ends

… then behind the scenes, it the same function looks like this due to the so called hoisting.

function fnFuntion(bVariable1) { // scope of function starts     

  var bVariable2; // declaration of bVariable2 got hoisted  

  if (bVariable1) {     

    bVariable2 = true; // declaration of bVariable gets hoisted to the top of its scope          

    console.log(bVariable1);   
  
  } 

} // scope of function ends

Before runtime and behind the scenes the bVariable2 was put to the top of its scope. The scope of bVariable2 is a local scope. It is the function fnFunction(). Because bVariable2 sits within fnFunction(). As explained above.

To sum up, hoisting means that a mechanism moves behind the scenes before runtime all of your JavaScript declarations to the top of their respective scopes.

And if you would not know about hoisting then you would be surprised about by the following code samples.

(Digression: An Undefined is thrown when a variable is not assigned to a value. If a variable is not initialized. A ReferenceError is thrown when it is tried to use a variable which does not exist. If a variable is not declared.)

function fnFunction(bBoolean) { // fnFunction is the local scope of bVariable2     

  if (bBoolean) {         

    var bVariable2 = false; // declare and initialize bVariable2                  

    console.log(bVariable2); // console output is as expected false     

  } 

} 

fnFunction(true);
// maybe still no surprise - first console output is false and the second is an Undefined 

function fnFunction(bBoolean) { // fnFunction is the local scope of bVariable2     

  if (bBoolean) {         
    
    var bVariable2 = false; // declare and initialize bVariable2                  

    console.log(bVariable2); // console output is as expected false     

  } else {                  

    console.log(bVariable2); // console output is an Undefined     

  } 

} 

fnFunction(true); 
fnFunction(false);
// but at the latest here comes the surprise - first console output is false. But the second output is a ReferenceError and not an Undefined as in the first code sample

function fnFunction(bBoolean) { // fnFunction is the local scope of bVariable2     

  if (bBoolean) {         

    var bVariable2 = false; // declare and initialize bVariable2                  

    console.log(bVariable2); // console output is as expected false     

  } else {                  
 
    console.log(bVariable100); // console output is a ReferenceError     

  } 

} 

fnFunction(true); 
fnFunction(false);

But now that you know about hositing you know what happens behind the scenes. Because behind the scenes it looks like this:

// behind the scenes declarations get moved to the top of their scopes 

function fnFunction(bBoolean) { // fnFunction is the local scope of bVariable2     

  var bVariable2; // declaration of bVariable2 gets moved to the top behind the scenes of its scope     

  if (bBoolean) {         

    bVariable2 = false; // initialize bVariable2                   

    console.log(bVariable2); // console output is as expected false     

  } else {                  

    console.log(bVariale2); // console output is an Undefined                 

    console.log(bVariable100); // console output is a ReferenceError     

  } 

} 

fnFunction(true); 
fnFunction(false);

Let

Now that hoisting is understood the new declaration keywords let and const are self -explanatory. If you should have not understood hoisting yet please read again the section above about hoisting.

If you use let instead of var in the second code sample from above then this happens:

function fnFunction(bBoolean) { // fnFunction is the local scope of bVariable2     

  if (bBoolean) {         
    
    // var bVariable2 = false; // we do not use var as before
    
    let bVariable2 = false; // now we use let instead of var
    
    console.log(bVariable2); // console output is as expected false     

  } else {                  

    // console.log(bVariable2); // Undefined was the error if used var
    
    console.log(bVariable2); // now the console output is a ReferenceError

  } 

} 

fnFunction(true); 
fnFunction(false);

As you see: No more hoisting. This means if a variable is declared through let then it does not get hoisted. If the variable is in a block scope.

And a block scope is just another scope. Like the further above explained function scope. A block scope starts with a { and ends with a }. Just like a function scope.

But the block scope refers not just to functions. But to all kind of blocks. For example, an if or for block:

if (true) { // here starts the block scope

  //

} // here ends the block scope

for (let i = 0; 0 < 10; i++) { // here starts the block scope

  //

} // here ends the block scope

And if you declare a let variable inside a block scope then this variable will not be hoisted.

if (true) { // here starts the block scope

  let sVariable = "string";

} // here ends the block scope

console.log(sVariable); // ReferenceError and not an Undefined

For the sake of clarity one more example with a var declared variable in a block scope. This var declared variable gets hoisted …

if (true) { // here starts the block scope

  var sVariable = "string";

} // here ends the block scope

console.log(sVariable); // Undefined and no ReferenceError

… and this looks behind the scences like this:

var sVariable;

if (true) { // here starts the block scope

  sVariable = "string";

} // here ends the block scope

console.log(sVariable); // Undefined and no ReferenceError

Const

The const keyword has the same scope features as the let keyword. But on top of that the const declaration has a bonus:

If a variable is declared as const then it is literally a constant. This variable is immutable:

var sVariableVar = "foo";
sVariableVar = "bar"; // possible

let sVariableLet = "foo";
sVariableLet = "bar"; // possible

const sVariableConst = "foo";
sVariableConst = "bar"; // Run Time Error: TypeError

This means it is not possible to assign a new value to a const declared variable.

But that does not mean, that it is not possible to mutable the object which a const variable holds:

const oVariable = {
  
  property: "value"

};

oVariable.property = "another value"; // possible


const aVariable = ["value"]; // an array is an object too

aVariable.push("another value"); // possible

When to use var, let, or const

This is a matter of taste. There are currently two main approaches.

The first approach is to use const as default. And to use let whenever there is the need to assign a new value to a variable. Plus, not to use var at all anymore. Event for variables which are supposed to be on the top global level.

const iVariable = 1; // const as default

let sVariable = "foo"; // let when the variable gets later a new value assigned
sVariable = "bar";

The second approach is to use let as default. And to use const whenever a variable should later not be assigned with a new value. Plus, not to use var at all anymore as well.

let sVariable = "foo"; // let as default
sVariable = "bar";

const iVariable = 1; // const when the reference to the variable should not be changed

I prefer the second way. Here is why: First of all, by using let as default there are every time two characters less to type. Plus, the two characters less make the code more clean.

And secondly, if the const keyword is only used for variables which indeed are supposed to be constant than this leaves a kind of a message to others who read your code.

Even if a const variable is mutable if it is an object. The const keyword is a signal to others that with the reference of this variable is not to be messed with. Obviously, it is not to be reassigned. Because you declared this variable const on purpose and not by default. Furthermore, if the object references an object then the object should not be mutated.

Anyway, no more use for var.

No Comments

Get A COMPLETE SAP Modules Overview infographic (free)

Plus, receive for free SAP tips & insights and all future infographics that are only shared with the private newsletter subscribers. 

Complete SAP modules/components overview infographic.
Categories
Latest Poll
Essential Ressources

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.

Menu