# Elevating Your JavaScript Game: The Essential ES6 Features You Need to Know

Javascript is mainly used for the front end programming and its new features makes it compatible with server side programming as well. Javascript was introduced around the year of 1995 that is almost 30 years back and after that many different features were introduced over the years. There were no classes initially and it was purely object based language.

It used to follow object based programming paradigm which is also known as OOPs concept. Recently around 2015 they launched ES6 features which gained popularity due to some drastic change in the structure of the language. After that a lot more features have been released in the ES series until ES14 which was last year in June 2023.

So, lets explore some of the cool features of ECMAScript community that completely changed the game of Javascript development and made it one of the most loved and used language on Stackoverflow survey of last seven years.

1. **let and const Declarations:**
    
    * `let` and `const` declarations provide block-scoped variables, meaning they are only accessible within the block (typically enclosed in curly braces `{}`). This contrasts with `var`, which has function scope or global scope. `let` variables can be reassigned, while `const` variables are constants whose value cannot be changed after initialization.
        
    * Variables declared using the `var` keyword are scoped to the function in which they are created, or if created outside of any function, to the global object. `let` and `const` are *block scoped*, meaning they are only accessible within the nearest set of curly braces (function, if-else block, or for-loop).
        
        ```typescript
        /**
         * All variables are accessible within functions.
         */
        function variableScope() {
        
          var x = 10;
          let y = 20;
          const z = 30;
        
          console.log(x); // 10
          console.log(y); // 20
          console.log(z); // 30
        }
        
        console.log(x); // ReferenceError: x is not defined
        console.log(y); // ReferenceError: y is not defined
        console.log(z); // ReferenceError: z is not defined
        
        variableScope();
        ```
        
        ```typescript
        /**
         * var declared variables are accessible anywhere in the function scope.
         */
        if (true) {
          var a = 10;
          let b = 20;
          const c = 30;
        }
        
        console.log(a); // 10
        console.log(b); // ReferenceError: b is not defined
        console.log(c); // ReferenceError: c is not defined
        ```
        
        `var` allows variables to be hoisted, meaning they can be referenced in code before they are declared. `let` and `const` will not allow this, instead throwing an error.
        
        ```typescript
        console.log(a); // undefined
        var a = 'foo';
        
        console.log(b); // ReferenceError: can't access lexical declaration 'b' before initialization
        let b = 'baz';
        
        console.log(c); // ReferenceError: can't access lexical declaration 'c' before initialization
        const c = 'bar';
        ```
        
        Redeclaring a variable with `var` will not throw an error, but 'let' and 'const' will.
        
        ```typescript
        var a = 'foo';
        var a = 'bar';
        console.log(a); // "bar"
        
        let b = 'baz';
        let b = 'qux'; // Uncaught SyntaxError: Identifier 'b' has already been declared
        ```
        
        `let` and `const` differ in that `let` allows reassigning the variable's value while `const` does not.
        
        ```typescript
        // This is ok.
        let a = 'foo';
        a = 'bar';
        console.log(a); // bar
        
        // This causes an exception.
        const b = 'baz';
        b = 'qux';
        console.log(b) // TypeError: Assignment to constant variable.
        ```
        
2. **Arrow Functions:**
    
    * Arrow functions provide a concise syntax for writing functions. They have implicit return if the function body is a single expression. Arrow functions also lexically bind `this`, meaning they inherit the `this` value from the surrounding code, which helps avoid issues with traditional function expressions.
        
    * Arrows is a new syntax for functions, which brings several benefits:
        
        * Arrow syntax automatically binds `this` to the surrounding code's context
            
        * The syntax allows an implicit return when there is no body block, resulting in shorter and simpler code in some cases
            
        * Last but not least, `=>` is shorter and simpler than `function`, although stylistic issues are often subjective
            
        
        **Example 01:** Arrow Function with No Argument
        
        If a function doesn't take any argument, then you should use empty parentheses.
        
        ```typescript
        let greet = () => console.log('Hello');
        greet(); // Hello
        ```
        
        **Example 02:** Arrow Function with One Argument
        
        If a function has only one argument, you can omit the parentheses.
        
        ```typescript
        let greet = x => console.log(x);
        greet('Hello'); // Hello 
        ```
        
        **Example 03:** Arrow Function as an Expression
        
        You can also dynamically create a function and use it as an expression.
        
        ```typescript
        let age = 25;
        
        let welcome = (age < 18) ?
          () => console.log('Baby') :
          () => console.log('Adult');
        
        welcome(); // Adult
        ```
        
        **Example 04:** Multiline Arrow Functions
        
        If a function body has multiple statements, you need to put them inside curly brackets `{}`.
        
        ```typescript
        let area = (r) => {
          const pi = 3.14;
          return pi * r * r;
        }
        
        let result = area(10);
        console.log(result); // 314
        ```
        
        *Note: Unlike regular functions, arrow functions do not have their own* `this`. The value of `this` inside an arrow function remains the same throughout the lifecycle of the function and is always bound to the value of `this` in the closest non-arrow parent function.
        
3. **Template Literals:**
    
    * Template literals allow embedding expressions within string literals using `${}` syntax. This enables multi-line strings without the need for concatenation and provides a convenient way for string interpolation.
        
4. **Destructuring Assignment:**
    
    * Destructuring assignment allows extracting values from arrays or objects into distinct variables using a syntax that mirrors the structure of the array or object. This feature simplifies code and makes it more readable, especially when working with complex data structures.
        
5. **Default Parameters:**
    
    * ES6 allows specifying default values for function parameters. If a parameter is not provided or is `undefined`, the default value will be used instead. This feature helps avoid the need for verbose checks for undefined values within functions.
        
6. **Rest and Spread Operators:**
    
    * The rest parameter (`...args`) allows collecting remaining arguments into an array, which is useful when working with functions that can accept a variable number of arguments. The spread operator (`...arr`) spreads elements of an iterable (like an array) into individual elements, facilitating tasks such as concatenation, copying, or passing array elements as function arguments.
        
7. **Classes:**
    
    * ES6 introduced class syntax, which provides a more familiar and intuitive way to create objects and define their behaviors. Classes support constructor methods, instance methods, static methods, inheritance, and super calls, making object-oriented programming in JavaScript more accessible.
        
8. **Modules:**
    
    * ES6 modules provide a standardized way to organize code into reusable and maintainable components. Modules encapsulate functionality and can export variables, functions, or classes for use in other modules. Import statements allow importing these exported functionalities into other modules, promoting modular code development.
        

These features represent just a portion of the enhancements introduced in ES6. They significantly improved JavaScript's expressiveness, readability, and maintainability, empowering developers to write more efficient and structured code. Additionally, ES6 laid the foundation for subsequent ECMAScript versions, which continue to expand and refine the language.
