DEV Community

Cover image for โœ๏ธ Learn ES6 With Me: Part One
yusufcodes
yusufcodes

Posted on • Updated on

โœ๏ธ Learn ES6 With Me: Part One

Introduction ๐Ÿ‘‹๐Ÿผ

Welcome to part one of this four-part series, where I'll be documenting the concepts I am currently learning as part of my journey to better understand the JavaScript Language.

In this part, I will be covering the following topics:

  1. Variable Declarations with Let and Const
  2. Blocks and Immediately Invoked Function Expressions
  3. Strings in ES6

Once I write and release the next parts, I will link them right below this line!
[empty space of nothing until I write and release the next parts]

Variable Declarations with Let and Const ๐Ÿ“ฆ

In ES6, there are two new ways of declaring variables using the following keywords: 'let' and 'const'.

Defining variables in ES6

// Two methods of declaring variables
let counter = 0;
const name = 'Yusuf';

console.log(counter); // Output: 0
console.log(name); // Output: Yusuf
Enter fullscreen mode Exit fullscreen mode

Effectively, the two statements above will do the same thing, such that two new variables, counter and name, are defined and set to some value.

What's the difference between 'let' and 'const' then?

The major difference between 'let' and 'const' is:

  • 'let': used for values which may change throughout the lifecycle of your JavaScript application.
  • 'const': used for values which cannot, and should not, change at any point in your application. These can be thought of as 'constant' values. **

** Thank you David for raising an excellent point in the comments - you can change values contained within a const structure itself (such as array elements) but not the entire variable itself (such as replacing the whole array contents). His input is below:

Comment Not Found


Another really good bit of explanation of const below:

Comment Not Found


Thinking back to the example of the counter and name variables we defined above, we used let for the counter and const for the name. This makes sense, right?
  • counter: this could be incremented or decremented in our program (changed), so it is appropriate to use let for this variable.
  • name: in most cases, a person cannot change their name, so we would want this to be defined using const, so it cannot be changed.

In fact, if we attempted to change the value of a variable defined using const, we will be greeted with a lovely error:

const name = 'Yusuf';
// Attempting to re-assign the value of name throws an error
name = 'new name!';
console.log(name);
Enter fullscreen mode Exit fullscreen mode

Displaying the console error which appears when trying to change the value of a const variable
This feature enables developers to define and save variables with one value, knowing that they won't be able to change it, intentionally or unintentionally, without JavaScript kicking up a fuss about it. Neat stuff I think.

Variable Declarations: Function Scoped vs. Block Scoped ๐Ÿ”

With the introduction of let and const, the way that the JavaScript Engine accesses these variables is different to how it is normally done when declaring variables with the var keyword in ES5.

We can describe let and const variables to be block scoped, and variables defined using var as function scoped. A scope can be thought of as the 'space' in which a particular value is accessible.

  • Block Scope: Variables defined in this scope are only available within the block that it is defined in
  • Function Scope: Variables defined in this scope are available throughout the function which it is defined in, even within other inner scopes

Below is a simple example of these two types of scopes, with an explanation afterwards:

// ES5: 'var'
function testingScopesOne()
{
    var num =  1;

    // Creating a new Block Scope
    {
        var num =  2;

        // Output: 2
        console.log(num);
    }

// Output: 2
console.log(num);
}

// ES6: 'let'
function testingScopesTwo()
{
    let num =  1;
    // Creating a new Block Scope

    {
        let num =  2;

        // Output: 2
        console.log(num);
    }

    // Output: 1
    console.log(num);
}

testingScopesOne();
testingScopesTwo();
Enter fullscreen mode Exit fullscreen mode

Code Explanation ๐Ÿ‘€

Above I have defined and executed two functions, testingScopesOne and testingScopesTwo.
I'll try to break down what I did in each function, the outcome, and how this links to the concepts of Function Scope and Block Scope:

  • In each function, I defined a variable called num, assigning it the value 1. The difference between them is that I use var in testingScopesOne and let in testingScopesTwo
  • After the variable definition and assignment, I create a new block using curly braces { ... }
  • Within the newly created block scope, I create a variable with the same name, num, and assign a new value of 2:
    • testingScopesOne: I used var and output the value within the current block scope.
    • testingScopesTwo: I used let and also output the value here.

Both output a value of 2, which is expected. Once we escape this block scope, however, we get a different outcome in the output statements:

  • Upon leaving the block scope, I once again output the value of 'num' in testingScopesOne and testingScopesTwo.
  • testingScopesOne output is 2, whereas testingScopesTwo outcome is still 1, which is the initial value we assigned to it in the beginning.

Why is this happening? ๐Ÿ˜ฎ

The testingScopesOne function is demonstrating the concept of Function Scoping.

Explanation: We defined a variable num using var, assigned it one value, then reassigned it another value within another scope of the function. This newly assigned value, 2, overrode the initial value of 1, showing that the scope of variables defined using var are Function Scoped.

The testingScopesTwo function, on the other hand, is demonstrating the concept of Block Scoping.

Explanation: We defined the variable num using let, and then within another scope of the function, we assigned a different value (2) to num. Instead, what happened here is, this new value did not save as it did in testingScopesOne, so when we output the value at the end of the function outside of this scope, the value remained at 1.

This is because, when we declared the variable num again within the block scope, it created a completely new variable, even though the name matched the initial variable we declared (num). This therefore demonstrates the concept of Block Scoping, where any variable defintion using let is only bound to the current block scope it is defined in.

Blocks and Immediately Invoked Function Expressions ๐Ÿƒ๐Ÿฝ

A block is any code which is encased within a set of curly braces:

{
    // Some code
}
Enter fullscreen mode Exit fullscreen mode

Blocks are commonly used in control structures such as if, for, else, etc. but is not limited to be used in these.

In ES6, we can use the concept of blocks to simplify the way we write Immediately Invoked Function Expressions (IIFEs).

Recap: What is an IIFE?

An IIFE is a function which is executed straight away (๐Ÿƒ๐Ÿฝ) upon definition - the JavaScript Engine recognises this as a function which needs to be executed right away.

The important thing about an IIFE is the ability to encapsulate all of the data that is used and defined within it. This means that access to anything from inside of an IIFE is not possible, unless such data is publicly defined. The reason for this is because, upon execution of an IIFE, a new scope is created, which is separate to the main parent scope.

IIFEs: ES5 vs. ES6

In ES5, we had to do the following to create an IIFE:

  • Declare an anonymous function
  • Wrap this function within parentheses
  • Add a pair of parentheses outside thse parentheses

A lot of work, right? Not to mention how messy the structure ends up looking.
Luckily, all we need to do in ES6 is write our code within a lone pair of parentheses...and that's it.

// ES5 IIFE
(function() {
    // Code
})();

// ES6 IIFE
{ 
    // Code
}
Enter fullscreen mode Exit fullscreen mode

ES6 IIFE: Example

Below is a simple example where we define an IIFE and declare a variable, myName, within it.
Accessing this variable within the IIFE works fine, whilst trying to access it from outside of the IIFE causes an error.

{
    const myName = 'Yusuf';
    console.log(myName); // Output: Yusuf
}
console.log(myName); // Error: myName is not defined
Enter fullscreen mode Exit fullscreen mode

Strings in ES6 ๐Ÿงต

The way we manipulate and interact with strings is considerably better in ES6.
There is one feature in particular, which is probably one of my most favourite things about ES6. And that is...string literals.

String Literals

Remember when you'd want to print out a string with some variables, such as a person's name? You would've had to do the following to achieve this:

// ES5 Strings
console.log('Hello' + name + ', welcome to this application!');
Enter fullscreen mode Exit fullscreen mode

With string literals, the awkwardness of adding the + operator between variables and starting / ending the string between each variable is now gone๐Ÿฅณ! The above console log can be achieved by doing the following:

// ES6 String Literals
console.log(`Hello ${name}, welcome to this application!`);
Enter fullscreen mode Exit fullscreen mode

Notable differences:

  • Use backticks instead of normal quotes
  • Enter any variables using the following syntax: ${ ... }, where ... represents the variable you want to display

You can also enter other simple snippets of JavaScript code within the ${ ... } structure, such as a call to a function. This function may return some value that you want to be displayed, in which case, you can just enter it directly into the string.

function returnName()
{
    return 'Yusuf';
}

console.log(`Hello ${returnName()}, welcome to this application!`);
// Output: Hello Yusuf, welcome to this application!
Enter fullscreen mode Exit fullscreen mode

ES6 String Methods

Aside from string literals, ES6 also comes with a few new functions that can be used on strings. Below is a simple demonstration of each:

// Method Name: startsWith
console.log('coffee'.startsWith('cof'));
// Output: true

// Method Name: endsWith
console.log('coffee'.endsWith('ee'));
// Output: true

// Method Name: includes
console.log('coffee'.includes('offe'));
// Output: true

// Method Name: repeat
console.log('hey '.repeat(4));
// Output: hey hey hey hey
Enter fullscreen mode Exit fullscreen mode

Conclusion

In part one of this four-part series, I've covered the following ES6 JavaScript concepts:

  • Using let and const to define variables, and comparing this to using var
  • Briefly touched on scopes, although more could be said on this as an entire article!
  • Covered Immediately Invoked Function Expressions and how we can achieve this using blocks
  • ES6 String manipulation and some new methods associated with them

Stay tuned for the next three parts of this series, which I'll post links to below once they've been released.

Some space for the next unreleased three parts of this series!

Note: I am in no way, shape or form, an expert when it comes to JavaScript. My idea and motive behind these posts are to help myself better understand these concepts as I learn them, whilst trying to give something back to the DEV community.
If there is anything fundamentally wrong with the information I've shared, please let me know. We're all still learning, and we can certainly do that together! ๐Ÿ˜Š

Find me on Instagram and Twitter, where I post about the tech that I'm currently working with, and document my journey as a Computer Science student๐Ÿ™‚.

Discussion (5)

Collapse
yusufcodes profile image
yusufcodes Author

Thanks David! Added your input to the article.

Collapse
yusufcodes profile image
yusufcodes Author

Hi David. Thank you so much for this input about const values. I've added it into the article - it is much appreciated. A clear distinction I did not pick up on here which I should have. ๐Ÿ˜Š๐Ÿ‘Œ๐Ÿฝ