ECMAScript Basics

 

 ECMAScript

  • ECMAScript is a language specification standardized by European Computer Manufacturers Association(ECMA).
  • All major JavaScript implementations adhere to the ECMAScript standard.

ECMAScript Defines

  • Language Syntax – parsing rules, keywords, statements, declarations, operators, etc.
  • Types – boolean, number, string, object, etc.

Prototypes and Inheritance
Standard Library of built-in objects and functions.

ES6
ECMAScript6 or ES6 is the sixth edition of the ECMA script Language specification standard.

TC39, is the committee that drafts the ECMAScript specifications. They follow a yearly model for defining new standards, where new features are added as they are approved, rather than waiting till all features are ready. Thus ES7 will contain all features proposed and approved in 2016.

Look Out!

As a part of this ECMAScript 6 course, we'll be exploring:

  1. Block scope (let and const)
  2. Default, Rest and Spread parameters
  3. Destructuring
  4. Arrow Functions
  5. Template Literals
  6. Classes and Modules
  7. Promise
  8. Maps and Sets
  9. Symbols
  10. Transpiring

Block Scope Variables

  • Block is a group of zero or more statements delimited by a pair of curly brackets {}.
  • Block scope variables are the ones that exist only within the innermost block that surrounds them.

In JavaScript, var is used to create variables. ES6, introduces 2 other keywords for declaring Block scope variables.

  1. let
  2. const

Let vs Var

let doesn't allow properties to be added to the global (window) object.

var x = 10;  

console.log(window.x)     // 10

let x = 10; 

console.log(window.x)    //  undefined

Let vs Var

let provides Block scope rather than function /global scope.

Using var:

function sum([array of args]) {​​​​​​​​

for(var i = 0; i < [array of args].length; i++) {​​​​​​​​

// some code

}​​​​​​​​

// variable i is available here.

}​​​​​​​​

Using let:

function sum([array of args]) {​​​​​​​​

for(let i = 0; i < [array of args].length; i++) {​​​​​​​​

// some code

}​​​​​​​​

// variable i is not available here.

}

Let vs Var

let doesn't allow re-declaring a variable in global situation

var x = 10;

var x = 11;  

console.log(x) // 11

let x = 10;

let x = 11; 

// Uncaught SyntaxError: Identifier 'x' has already been declared

Understanding Const

const keyword is also used to declare Block Scope variables in ES6. These variables can not be changed once declared unlike let or var.

let x = 10;                                           

x = 20;

// console.log(x) => 20 

const x = 10;

x = 20;

//  Uncaught TypeError: Assignment to constant variable.

Freeze

Const make objects immutable, but it's value can still be modified. To prevent the modification and make object immutable, use the freeze() function.

const x = { name: "Abc", age: 20 };

x.age = 25;

console.log(x);

//{ name: 'Abc', age: 25 }

const x = Object.freeze({ name: "Abc", age: 20 });

x.age = 25;

console.log(x);

//{ name: 'Abc', age: 20 }

Parameters and Arguments

Parameters (or formal parameters) are given in the function declaration, whereas Arguments (or actual parameters) are passed to the function.

Example:

function foo(a,b) { 

       //do something 

}

foo (10,20);

In this function, a and b are parameters, while 10 and 20 are the arguments.

ES6 offers 3 types of parameters and we will learn about them in this module.

Default Parameters

Default parameters are the parameters with an initialised value.

Invoking a function without passing any arguments, would assume default values and process the request.

Example in JavaScript

function foo(a, b) {

    console.log(a, b);

}        

foo();           // undefined undefined

foo(5, 10)  // 5 10

Example in ES6:

function foo(a = 10, b = 20) {

    console.log(a, b);

}

foo();            // 10 20

foo(5, 10);  // 5 10

Rest Parameter

Rest allows indefinite number of parameters in one single array. Notation ...<paramname> is used to define Rest Parameter.

Example in JavaScript

function sum() {

var args = Array.prototype.slice.call(arguments);

// converts args to array

var result = 0;

args.forEach(function (args) {

result += args;

} );

return result;

}

Example in ES6

//args is rest parameter

function sum(...args) {

    var result = 0;

    args.forEach(function(args) { result += args; } )

    return result;

}

let [x,y,z] = [1, 2, 3];

let add = sum(x, y, z);

console.log(add);  // output: 6

Spread Operator

Spread Operator ( ...) is used to spread an array elements into parameters.

Usage in code: ...array_variable_name

Example in Javascript

function sum(x, y, z) {

 return x+y+z;

}

let args = [1, 2, 3];

let add = sum.apply(null, args); 

console.log(add);

Example in ES6

function sum(x, y, z) {

 return x+y+z;

}

let args = [1, 2, 3];

let add = sum(...args);

console.log(add);  

Using Spread Operator

Spread Operator can be used for

Concatenation of arrays

 var parts = ["shoulder", "knees"];

 var bodyParts = ["head", ...parts, "and", "toes"]; 

 console.log(bodyParts)

Output : ["head","shoulder","knees","and","toes"]


Math Functions

    let numbers = [9, 4, 7, 1];

    console.log(Math.max(...numbers));

Output : 9


Destructuring arrays and objects.

let [x, y, ...z] = [1,2,3,4,5,6];           

would mean x = 1, y = 2, z = [3,4,5,6]

let {x, y, ...z} = {x: 1, y: 2, z: 3, a: 4};    


More on Spread and Rest

By now, you must have understood that the Rest and Spread operators added in ES6 / JS2015 drastically improve the ability to deal with unknown numbers of function parameters, and array and hash manipulation.

Practice Default Parameters

function sum(x, y) {

         return x+y;

}

Modify the above function to satisfy the following conditions

sum(); // output => 5

sum(2); // output => 5

sum(2, 6); // output =>

would mean x = 1, y = 2, z = { z: 3, a: 4 }   

HandsOn 2 :  es6-sum-number :

File  index.js

const sum = (...num) => {

  var result = 0;

  num.forEach(function(num) {

    result+=num;

  }

  );

  return result;

}

module.exports = {sum}


Practice Spread Parameters

function spreadParams(firstParam, secondParam, thirdParam) {

     console.log(firstParam);

     console.log(secondParam);

     console.log(thirdParam);

}

spreadParams([1, 2, 3])

Modify the function invocation to achieve the following output.

firstParam => 1, secondParam => 2, thirdParam => 3


Destructuring Content

  • Destructuring is a convenient way of extracting multiple values from data stored in arrays or objects into distinct variables.
  • JavaScript allows constructing arrays / objects, one property at a time or multiple properties at a time.
        const name = { first: 'Kim', last: 'Johnson' };
  • However, extracting data had to be done one property at a time. There was no way to extract multiple properties at a time.
    const firstname = name.first;
    const lastname = name.last;
  • Destructuring in ES6, addresses this problem!


Destructuring Arrays

Taking array elements directly into variables:

var [one, two, three, four] = ["chennai", "mumbai", "goa", "cochin"];  

//console.log(one);  => chennai

Skipping values and taking second array element in variable two:

var [,two,,]=["chennai", "mumbai", "goa", "cochin"];

//console.log(two);  => mumbai

Destructuring Nested Arrays:

 const [one, two, three] = [ 1,  [2,3],  [4,5] ];    

//one=> 1 two=> [2,3], three=>[4,5]


Destructuring Nested Objects

Declaration below would assign values a = 1, b = 2 and c = { four: 4, five: 5}

const {one: a, two: b, three: c}  = { one: 1, two: 2, three: { four: 4, five: 5} } ;   

For readability we can use one:one instead of one:a. Declaration below would assign:

one = 1, two = 2 and three = { four: 4, five: 5}

const {one: one, two: two, three: three}  = { one: 1, two: 2, three: { four: 4, five: 5} } ;

Similarly, the declaration below will assign:

one = 1, two= 2 and three= 3

const {one, two, three} = { one: 1, two: 2, three: 3 };

Default values can also be used in destructuring

const {one, two, three, four=4} = { one: 1, two: 2, three: 3 };

Array Function : 

  • Arrow functions in ES6 are the modified and abbreviated syntax of JavaScript functions.
  • These functions make use of => token and hence known as Fat Arrow functions.
  • Also, Arrow functions are less verbose than the traditional function expressions.


Function Definition

JavaScript functions with multiple, single and no parameters

 var add = function(x, y) { return x+y; }

 var square = function(x) { return x*x;}

 function sub() => { return expression; } 

ES6 Equivalent

var add = (x, y) => { return x+y; }

var square = (x) => { return x*x; }

    OR

var square = x => { return x*x; } 

//Parantheses are optional for single parameter 

var sub  = () => expression 

//return and {} are optional for function with single statement


Function Expression

Arrow functions can also be used as function expressions to return object literals. The function body should be wrapped in parantheses () to achieve this.

Example in JavaScript

var bio = function(name, age, country) {

    return {name: name, age: age, country: country};              

};

Example in ES6

var bio = (name, age, country) => ({name: name, age: age, country: country}) 


More on Arrow Functions

In this video, we will look at the various ways we can write arrow functions, where the inspiration came from. And finally how the this keyword works inside of an arrow function.

Template Literals

Template string makes it easy to create strings that are longer and have lot of dynamic content (variables) with exact amount of spaces, line breaks and indentation.

Template literals allows to:

Create complex strings easily.

Evaluate an expression in templates.

Build complex html and xml templates (template functions).

Instead of single quotes or double quotes, ES6 uses BACKTICK or OPENQUOTE ( " ` " ) character to create template literals.

Creating complex strings

Creating multiline strings no longer requires slash n (\n)

Creating a multiline string in JS:

let bio = "Wendy Harper \n Software Engineer - TCS \n 3 Years in Web development"

Creating the same in ES6

let bio = `Wendy Harper

           Software Engineer - TCS

           3 Years in Web development` 


Evaluating Expressions

The literal is delimited by backticks and the interpolated expressions inside the literal are delimited by ${ variable }.

Template literals always produce strings.

Example of interpolation of Expressions:

let fN = `Wendy`;

let lN = `Harper`;

console.log(`My name is ${fN} ${lN}`);  

Alternatively we can also use more complex object.

let person = {

    fN: `Wendy`,

    lN: `Harper`,

    name: function() {

        return `My name is ${this.fN} ${this.lN}`;

    }

};

person.name();

Output in both cases would be: My name is Wendy Harper


Creating HTML Templates

Without using any templating libraries such as moustache or handlebars, we can create templates using template literals, which can be reused.

const wendy = {  "id": 1,

                 "firstName": "Wendy", 

                 "lastName":  "Harper",

                 "city":      "Tulsa"

            }

function bio(person) {

return `<p>

    <h1>

        <span>${person.firstName}</span>

        <span>${person.lastName}</span>

     </h1>

        <address>${person.city}</address>

    </p>`

}

bio(wendy)

Output:

 <p>

    <h1>

        <span>Wendy</span>

        <span>Harper</span>

    </h1>

    <address>Tulsa</address>

</p>

Class in ES6

  • Class is just syntactical sugar over JavaScript prototype based inheritance.
  • ES6 classes provide simple and clear syntax for creating objects and deal with inheritance.
  • Class Definition Includes:
  • Class Declaration:

class ArithmeticOperations {

    constructor(x, y){

         this.x = x;

         this.y = y;

    }

    multiply() {

         return this.x * this.y;

    }

}                                               

Class Expression:

let ArithmeticOperations = class {

     // same as class definition above

}

types of Methods

  • Constructor: is a special method for initializing and creating objects with a class. A class can have at the most one constructor.
  • Static Methods: are method on constructor function itself. They can be created using static keyword. They cannot be invoked using instances.

Example:

class Food {

  static describe () {

    console.log("Food is a data type for storing macronutrient information.");

  }

}

Food.describe();  

Prototype Methods: are any methods which are not constructor or static method.

Inheritance - SubClassing

extends keyword can be used to make a class a subclass(child) of another class.

class ArithmeticOperations{

  constructor(x,y) {

        this.x = x;

        this.y = y;

    }

  multiply() {

      return this.x * this.y;

    }

}


class Addition extends ArithmeticOperations {

    sum() {

        return this.x + this.y;

    }

}

let operation = new Addition(2, 3);

operation.sum();   //  5

operation.multiply(); // 6

Inheritance - SuperClassing

Parent class methods can be invoked using super keyword.

class DoubleAdd extends Addition {

    doubleAdd() {

        return 2 * super.sum();

    }

}

var x = new DoubleAdd(2, 3);

x.doubleAdd();      //  10


Maps and Sets

Maps

  • Maps are objects that associate a key to a value.
  • Maps allows both primitives and objects as key and value. But object allows only string keys.

Set

  • It is a collection of unique values.
  • Values can be primitive or objects.

WeakSet and WeakMap

  • WeakSet and WeakMap are similar to Set and Map respectively except that:
  • Values are easily garbage collected in WeakSet or WeakMap.
  • They cannot be iterated.
  • Set references are strong pointers, while WeakSet references are weak pointers and vice versa for map.
  • Accepts only objects as keys, no primitives.
  • Few methods such as: .values(), .keys, .entries, and .size do not work.


Symbols

  • Symbols are new unique, immutable, primitive data type just like Number, String, and Boolean. They were originally meant to provide private properties.
  • Symbol() function can be used to create symbols.
        const mySymbol = Symbol(); 
  • Symbol can not be instantiated using new keyword.
        var sym = new Symbol(); // TypeError
    • let symbol1 = Symbol();
    • let symbol2 = Symbol();   
    • console.log( symbol1 === symbol2 );  //false   


Global Scope Symbols

  • Symbol() function will not create a global symbol that is available in the whole codebase.
  • To create global scope Symbols, use following methods.
    • 'Symbol.for()'
    • 'Symbol.keyFor()'
  • These methods can be used to set and retrieve symbols from the global symbol registry.

Global Scope Symbols

Symbol.for(key) method searches for existing symbols with the given key and returns it, if found. Otherwise, it creates a new symbol in the global symbol registry with this key and then returns the symbol.

Symbol.for('bar') === Symbol.for('bar'); 

// true, both are same

Symbol('bar') === Symbol('bar');  

// false, as Symbol() creates new Symbol each time it is called

Global Scope Symbols

Symbol.keyFor(key) method is essentially opposite of Symbol.for(key).

Instead of passing a key to get a symbol, pass a symbol to get a key.

var sym1 = Symbol("desc");    

// Local symbol      

var sym2 = Symbol.for("desc");   

// Global symbol  

console.log(Symbol.keyFor(sym1));   

// undefined  

console.log(Symbol.keyFor(sym2));   

// desc    


Symbols as Object Keys

Symbols can be used as object keys to have (semi) private properties in JavaScript.

// Defining symbol 

let email = Symbol(); 

// Defining object "user"

let user = {      

    name:"praveen", 

    age : 30, 

//Symbol as key in array 

    [email] : "praveen@gmail.com" 

 };  

Symbols are visible if accessed directly:

 console.log(user[email]);  

// praveen@gmail.com


Accessing Object Symbols

Iterating Object.keys() and Object.getOwnPropertyNames(), using for loop or methods, would list just the name and age.

Email will not be displayed as it is private.

for (var i in user) { console.log(i);}

Object.keys(user); 

Object.getOwnPropertyNames(user); //Output:["name","age" ]


Accessing Object Symbols

Symbols in Objects can be accessed via Object.getOwnPropertySymbols or Reflect.ownKeys, thus making them public for all to see.

Object.getOwnPropertySymbols() returns an array of symbol-based keys

 Object.getOwnPropertySymbols(user);  

 //Output:  [ Symbol() ]

Reflect.ownKeys() will return an array of all keys & symbols.

 Reflect.ownKeys(user)    

 //Output: [ "name", "age", Symbol() ]

Hands-on : es6 Generator with arguments

function* person() {

    let age = yield 'Age please';

    console.log(age);                                                    

    let location = yield 'Your age is ' + age + 'Your location please....';

    console.log(location);        return location;    }

let iterator = person();

iterator.next();    

// Object {value: "Age please", done: false}

iterator.next(10);  

// Object {value: "Your age is 10 

//              Your location please....", done: false}

iterator.next('LA') 

//   Object {value: "LA", done: true}


Generator with arguments

function* person() {

    let age = yield 'Age please';

    console.log(age);                                                    

    let location = yield 'Your age is ' + age + 'Your location please....';

    console.log(location);                                                        return location;                                                          }

let iterator = person();

iterator.next();    

// Object {value: "Age please", done: false}

iterator.next(10);  

// Object {value: "Your age is 10 

//              Your location please....", done: false}

iterator.next('LA') 

//   Object {value: "LA", done: true}


Transpiling

  • Transpilingis a specific term for taking source code written in one language and transforming into another language.
  • As not all browsers support all ES6 features, ES6 code is converted into ES5 so it can be read by all browsers.
  • Popular Transpiling Tools
  • Few of the popular transpiling tools are: Babel.js, Webpack, Closure and Traceur.
  • In this course, we will be focusing on Babel. Babel offers better readibility and understandability of the ES5 code it generates, after transpiling and makes the work of any JavaScript developer easy.
  • Sample of how Transpiling Works

Function to add any number of integer arguments Code in ES6:

let additionResult=(...arr)=>{

    var sum=0;

    for(var i=0; i<arr.length; i++){

    sum+=arr[i];

    }

return sum;

}

Code Transpiled by Babel into ES5:

var additionResult = function additionResult() {

    for (var _len = arguments.length, 

         arr = Array(_len), _key = 0; 

         _key < _len; _key++) {

            arr[_key] = arguments[_key];

    }

var sum = 0;

for (var i = 0; i < arr.length; i++) {

        sum += arr[i];

    }

return sum;

};

Output of both these functions would be same. additionResult(1,2,7,5,6); // output: 21


Using Babel

Add below script code in <head> section of HTML page.

<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/6.1.19/browser.js"></script>

//source: https://cdnjs.com/libraries/babel-core

Rename "text/javascript" to "text/babel"

<script type="text/babel">

 var nameBuilder = (firstName="Michael", lastName="Jackson") => {

  console.log(` ${firstname} ${lastName} `);

 }

</script>

This approach enables in-browser transformation without a need to install anything.

However, it converts whole code into ES5 during runtime of project, which might make the application slow.


ES6 Course Summary

This brings us to the end of the course. In this course, we have covered all the new features available through ES6 and also learnt how to use Babel to transpile the code to be compatible with all browsers. ES6 is a biggest update to JavaScript and we encourage you to continue and stay updated about the new features that will be added in future versions of ECMAScript.

Comments

Popular posts from this blog

Prectice page

Angular 2.0 complete course With Hands-on