This is the Basic to Advance Concepts of javascript ES5 & 6.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Basic to Advance concept of javascript ES5 & ES6</title>
</head>
<body>
    
    <script>
        /*
        *
        * Difference Between Var and Let
        * 
        */
         // var can accessable in function
         // var scope under a function
         function sayHello(){
             for (var i = 0; i < 5; i++) {
                 console.log(i); 
             }
             console.log(i);
         }
         sayHello();// output 0,1,,2,3,4,5

        // now check the let
        // let scope under a block
        function sayHelloLet(){
            for (/*let instead of var*/var i = 0; i < 5; i++) {
                console.log(i); 
            }
            console.log(i);
        }
        sayHelloLet();// output 0,1,,2,3,4,Uncaught ReferenceError: i is not defined
         
        /*
        *
        * Object
        * 
        */
        const obj = {
            operate : 'Sum',
            func: function(a,b){
                return a+b;
            },
            func2(a,b){
                return a+b;
            },
            //func and func2 have same functionality
        };
        console.log(obj.func(2,6));
        console.log(obj.func2(2,8));
        //we use the below method if the index is dynamic
        var callIndex = 'func2';
        console.log(obj[callIndex](15,20));

        /*
        *
        * this
        * 
        */
        const person = {
            name:'Shabair',
            detail(){
                console.log(this);
            }
        };
        person.detail(); //output {name: "Shabair", detail: ƒ}

        //below method returns widows object instead called object due to strick mode inable for security reason
        const walk = person.detail;
        walk();//window {window: Window, self: Window, document: document, name: "", location: Location, …}

        //solve the above strick problem we bind function to an object
        const walkSolve = person.detail.bind(person);
        walkSolve(); // output: {name: "Shabair", detail: ƒ}

        /*
        *
        * Arrow function
        * 
        */
        //Simple in javascript
        const func1 = function(num){
            return num * num;
        }
        console.log("func1 : "+ func1(2));

        //In ES6
        const funcES6_1 = (num) => {
            return num * num;
        }
        console.log("funcES6_1 : "+ funcES6_1(4));

        //In ES6 (in case of single parameter)
        const funcES6_2 = num => {
            return num * num;
        }
        console.log("funcES6_2 : "+ funcES6_2(4));

        //In ES6 (in case of zero parameter empty paratheses)
        const funcES6_3 = () => {
            return 5 * 2;
        }
        console.log("funcES6_3 : "+ funcES6_3());

        
        //In ES6 (in case of single link body)
        const funcES6_4 = num => num * num;
        console.log("funcES6_4 : "+ funcES6_4(4));
        
        //uses of arrow function
        const jobs = [
            {id: 1, isActive:true},
            {id: 2, isActive:true},
            {id: 3, isActive:false},
        ];

        //without arrow function
        const activeJobs = jobs.filter(function(job){ return job.isActive; });
        console.log(activeJobs);
        
        //with arrow function
        const activeJobs2 = jobs.filter( job => job.isActive );
        console.log(activeJobs2);
        /*
        *
        * Arrow function and this
        * 
        */
       //this function return the window object instead voice because setTimeout is stand alone 
       //function and strick mode doesn't override it. To tackle this problem we use arrow function.
        const voice = {
            talk(){
                setTimeout(function(){
                    console.log("this :" ,this);
                },1000);
            },
        };

        voice.talk();

        //first solution via pre-define var
        const voicePerDefine = {
            talk(){
                var self = this;
                setTimeout(function(){
                    console.log("this via self:" ,self);
                },1000);
            },
        };

        voicePerDefine.talk();

        //Seond solution via arrow function
        const voiceArrowFunction = {
            talk(){
                setTimeout(() => console.log("this in the voiceArrowFunction :" ,this), 1000);
            },
        };

        voiceArrowFunction.talk();

        /*
        *
        * Array Map
        * 
        */
        //without arrow function
        const colors = ['red', 'green', 'white'];
        const items = colors.map(function(color){
            return `<li>${color}</li>`;
        });
        console.log(items);

        //with arrow function
        const colorsWithArrowFunc = ['red', 'green', 'white'];
        const itemsWithArrowFunc = colorsWithArrowFunc.map( color => `<li>${color}</li>` );
        console.log(itemsWithArrowFunc);

        /*
        *
        * Object Destructuring
        * 
        */
        // get object value without destructuring
        const myDetail = {
            street:'Lodhi Street',
            age: 26,
            country: 'Pakistan'
        };

        console.log(`Street is: ${myDetail.street}. Age is: ${myDetail.age}. Country Is: ${myDetail.country}`);

        //with destructuring
        var {street, age, country:cntry} = myDetail;
        console.log(`Street is: ${street}. Age is: ${age}. Country Is: ${cntry}`);

        /*
        *
        * Spread Operator: Used for combine two or more than two arrays
        * 
        */
        //without Spread operator
        var first = [1,2,3];
        var second = [4,5,6];

        console.log(first.concat(second));

        //with Spread Operator
        console.log([...first, 'a', ...second, 'b']);

        // make a clone
        console.log([...first]);

        //In the case of Object
        var std1 = {name:'Shabair'};
        var std1MoreDetail = {age:20};

        console.log({...std1, ...std1MoreDetail, Country: 'Pakistan'});




    </script>
</body>
</html>