πŸ“œ ⬆️ ⬇️

ES6 Simple language

Pattern Literals


Sample literals are enclosed in backquotes (``) instead of double or single. They may contain substitutions, denoted by a dollar sign and curly brackets ($ {expression}).

Example:

var name = "bill"; console.log(`Hello ${name}`); // Hello bill 

Directives let const


The scope of variables declared by the let and const keywords is the block in which they are declared, and all its sub-blocks. In this work, the let directive is similar to the var directive. The main difference is that the scope of the variable declared by the var directive is the entire function in which it is declared. In addition, variables declared with the const keyword are constant constants. When declaring a variable with the const keyword, you must use an assignment operator to set a constant value.
')
An example of the difference between the global and block scope:

 function myFunction() { if (true) let a = 5; console.log(a); //SyntaxError   a     if if (true) var b = 5; console.log(b); //5   b     } 

Arrow functions


The expressions of the switch functions have a shorter syntax compared to functional expressions and are lexically bound to the value of this (but not attached to its own this, arguments, super, or new.target). Arrow functions are always anonymous.

Examples of arrow functions:

 const sum = (a, b) => a + b; const squared = a => a*2; const myFun = () => someFun(); const Fun = (data) => { data.response } 

For ... of


The for ... of operator performs a loop traversal of iterated objects (including Array, Map, Set, an object of arguments and the like), calling at each iteration step operators for each value from the various properties of the object.

Why SHOULD NOT use a for ... in loop to iterate? Because, depending on the engine, JavaScript can iterate in random order, which can lead to unpredictable results. In addition, the iteration variable is a string, not a number, which means that if you are going to perform any calculations with a variable, you will need to concatenate the strings instead of adding them. So in order to avoid logical errors should not use it!

For ... of loop

 for (var i of arr) //for ( of ) arr[i] = "something value" 

Calculated Names


The syntax for declaring objects and their elements supports computed property names. This allows brackets [] to add an expression that will be evaluated as the name of a property. It resembles patterned literals.

Example of calculated names:

 var a = () => "world"; var a = { ["a" + (10 - 6)]: { ["some" + "string"]: true, [10 + 20]: 10, [`hello ${a()}`]: a() } } 


Object.assign ()


The Object.assign () method is used to copy the values ​​of all of its own enumerated properties from one or more source objects to the target object. After copying, it returns the target object.

An example of using Object.assign ():
 var = newStudent = Object.assign({}, person, student); 

Now newStudent contains all the properties and methods of the person and the student.

In ES5, when creating a duplicate object, a mutation effect occurs when changes in the duplicate are reflected on the parent object.

 var A = { a: 1 }; var B = A; Ba = 2; 

It would seem that we change the property of object B BUT after executing this code, and Ba and Aa will be equal to 2. The situation can be corrected using the Object.assign () method.

 var A = { a: 1 }; var B = Object.assign({}, A); Ba = 2; 

Now only Ba will be equal to 2 a, Aa still equal to 1.

In Object.assign (), you can immediately set the property values ​​and declare new ones by passing them as an argument.

 var A = { a: 1 }; var B = Object.assign({ b: 3}, A, { a: 2 }); 

Property b is created and the value of property a is changed from the parent object.
And now Ba is 2. Bb is 3.

Remaining parameters


The syntax of the remaining parameters of the function allows you to represent an unlimited set of arguments in the form of an array. If the last named argument of the function has a prefix ..., then it automatically becomes an array with elements from 0 to theArgs.length in accordance with the actual number of arguments passed to the function.

An example of using the syntax of the remaining parameters:

 function name (a, b, ...c) {} name (0, 1, 2, 3,) 

In this example, a = 0 b = 1 c [0] = 2 c [1] = 3
If the remaining parameter is not passed, it will be an empty array (unlike normal parameters, it will never be undefined).

This syntax can be used not only in function arguments but also in other places, for example, to copy and merge arrays:

 var a = [ 0, 1, 2 ]; var b = [ 3, 4, 5 ]; var c = [ ...a, ...b ]; // [ 0, 1, 2, 3, 4, 5 ] 

Default settings


Now you can define default values ​​(other than undefined) to parameters that were not passed to the function.

An example of using default parameters:

 function myFun(a=5) { return a*a; } console.log(myFun()); // 25 

Destructuring assignment


The syntax for destructive assignment in JavaScript expressions allows you to extract data from arrays or objects using a syntax similar to declaring an array or literals in an object.

Example of destructive assignment:

 var a, b, rest; [a, b] = [1, 2]; console.log(a); // 1 console.log(b); // 2 [a, b, ...rest] = [1, 2, 3, 4, 5]; console.log(a); // 1 console.log(b); // 2 console.log(rest); // [3, 4, 5] ({a, b} = {a:1, b:2}); console.log(a); // 1 console.log(b); // 2 

Map and Set


Map - An object containing key-value pairs and preserving the insertion order. Any value (both objects and primitives) can be used as keys.

Example:

 var myMap = new Map(); var keyObj = {}, keyFunc = function () {}, keyString = "a string"; //   myMap.set(keyString, "value associated with 'a string'"); myMap.set(keyObj, "value associated with keyObj"); myMap.set(keyFunc, "value associated with keyFunc"); myMap.size; // 3 //   myMap.get(keyString); // "value associated with 'a string'" myMap.get(keyObj); // "value associated with keyObj" myMap.get(keyFunc); // "value associated with keyFunc" myMap.get("a string"); // "value associated with 'a string'" //   keyString === 'a string' myMap.get({}); // undefined,   keyObj !== {} myMap.get(function() {}) // undefined,   keyFunc !== function () {} 

Difference Map from Object:

  • Object keys are Strings and Characters, while any value can be a Map key, including functions, objects, and primitives.
  • Unlike Objects, the keys in the Map are ordered. Thus, during Map iteration, the keys are returned in the order of insertion.
  • You can easily get the number of elements in the Map using the size property, while the number of Object elements can only be determined manually.
  • Map is an iterable object and can be iterated directly, while the Object requires manual retrieval of a list of keys and their iteration.
  • The object has a prototype and therefore has a standard set of keys that, if careless, may intersect with your keys. Since the release of ES5, this can be changed with map = Object.create (null).
  • Map may have better performance in cases of frequent addition or deletion of keys.

Properties and methods:

  • Map.prototype.size - Returns the number of key / value pairs on a Map.
  • Map.prototype.set (key, value) - Adds the transferred key / value pair to the Map. If the specified key already exists, it will be overwritten by the new value.
  • Map.prototype.get (key) - Returns the value of the passed key. If there is no key, then undefined
  • Map.prototype.has (key) - Returns true if the transferred key exists and false if it does not exist.
  • Map.prototype.delete (key) - Deletes the specified key / value pair and returns true. Returns false if the key does not exist.
  • Map.prototype.clear () - Removes all key / value pairs from the Map.
  • Map.prototype.keys () - Returns an iterator of keys on the Map for each item.
  • Map.prototype.values ​​() - Returns an iterator of the values ​​in Map for each item.
  • Map.prototype.entries () - Returns an iterator of the [key, value] array on the Map for each element.

Set - Allows you to save unique values ​​of any type, both primitives and other types of objects. Set objects represent collections of values ​​that can be traversed in order to insert items. The value of an element in a Set can be present only in one instance, which ensures its uniqueness in the Set collection. For the rest, no different from Map.

Classes


Constructors


 class Student { constructor(name) { this.name = name; } } var robert = new Student('Robert'); console.log(robert.name); // Outputs 'Robert' 

When creating new objects from a class, constructor () will be launched, which is necessary for initializing objects.

Methods


 class Student { constructor(name) { this.name = name; } sayName() { return "Hi my name is " + this.name; } static stMethod () { // do something } } var robert = new Student('Robert'); Student.stMethod(); //        ,       console.log(robert.sayName()); // "Hi my name is Robert" 


Getters and Setters


 class Student { constructor(name) { this.name = name; } get Name() { return this.name; } set Name(newName) { if(typeof(newName) != "string") throw new Error("Name is not a string!"); else this.name = newName; // Robert } } var robert = new Student('robert'); robert.Name = "Robert"; console.log(robert.Name); 

  • setter - Required for validations of written parameters (as in the example above)
  • getter - Required for getting properties (although you can get them directly). Cannot have arguments

In ES6, there is no built-in encapsulation, but you can organize it yourself. For example, like this:

 var Student = (function () { let privateProps = new WeakMap(); class Person { constructor(name, Age) { this.name = name; // public privateProps.set(this, {age: Age}); // private } get Age() { return privateProps.get(this).age; } set Age (newAge) { privateProps.set(this, {age: newAge}); } } return Person; })(); var robert = new Student('Robert', 19); robert.Age = 20; console.log(robert.Age); // 20 

Inheritance


Using the extends keyword, you can inherit the properties and methods of another class.

 class Person { constructor (age) { this.age = age; } sayAge () { return this.age; } } class Student extends Person { constructor (name, age) { super(age); this.name = name; } sayFull () { return `Hello my name is ${this.name} and I'm ${super.sayAge()} years old` } } var robert = new Student("Robert", 19); console.log(robert.sayFull()); // Hello my name is Robert and I'm 19 years old 

  • In the child class, you need to call super () before using this to call the parent class constructor.
  • super () can be used to call methods of the parent class from a child.

Promise


Promise is a new way to do asynchronous computing without a race condition.
Promise can be in three states:

  • pending: initial state, not met and not rejected.
  • fulfilled: the operation completed successfully.
  • rejected: operation completed with an error.

Creating promises is done as follows:

 const myPromise = new Promise((resolve, reject) => { resolve(someValue); //   reject("failure reason"); //  }); 

The function object with two arguments, resolve and reject, causes the promise to succeed, the second one rejects it.

To provide the function with promises functionality, you just need to return the Promise object in it.

Handler execution and reject promises are attached using .then.

This example creates an asynchronous http request:

 const URL = "https://getfestivo.com/v1/holidays?api_key=f8f42551-eb66-49d2-bcba-b8e42727ddfb&country=US&year=2019"; //  API      function asyncHttpRequest (url) { return new Promise((resolve, reject) => { //  promise if (url == undefined) //     url reject(new Error("Expected url and received nothing")); else //     url :D { resolve(() => { fetch(url).then((response) => { //   return response.json(); //    JSON   }).then((myJson) => { return(console.log(myJson)); //      }); }); } } );} asyncHttpRequest(URL).then((result) => result(), (error) => console.log(error)); 


Iterators


Iterable - This is an object whose contents can be iterated.
An iterable object differs from a non-iterable one in that it has a special method that returns an object for which the special symbol is used: Symbol.iterator

 Iterable { [Symbol.iterator]() } 

The object returning this method is formally called an iterator.
The iterator has only one method next ()
 Iterator { next(); } 

Which returns an object (let's name it itreratorResult) with two properties done and value
 IteratorResult { done, value } 

done indicates whether there is another value in the sequence being searched, and value contains the next element of the sequence.

A loop for ... of has been added to iterate through the objects being iterated. Why, then, need an iterator? To be honest ... I do not know. The iterator is a utility method, and you will have to deal with it vryatle. But the understanding of what he is is necessary.
Actually, the iterator itself looks like this:
 function makeIterator(array){ var nextIndex = 0; return { next: function(){ return nextIndex < array.length ? {value: array[nextIndex++], done: false} : {done: true}; } } } 

Generators


Generators are a special type of function that works as an iterator factory. A function becomes a generator if it contains one or more yield operators and uses the function * syntax.

And if it is easier to say, then generators are a new kind of functions that can suspend their execution and return an intermediate result and resume execution later.
Let's look at a normal function that performs some mathematical calculations and returns a result:
 function myFunction (a) { a = a*2; a = a - 1; return a; } console.log(myFunction(5)); // 9 

Now take a look at a similar function generator:
 function* generator(a) { a = a*2; yield a; a = a - 1; yield a; } var it = generator(5); console.log(it.next().value); // 10 console.log(it.next().value); // 9 

As mentioned earlier, generators can suspend their execution and return an intermediate result. This example shows that at the time of the first call, the function seems to suspend its execution at the first yield point and returns the result of the first expression. In the second call, the function continues from the previous blockpoint and moves to the next, returning the result of the next expression.

Functions generators provide a powerful tool for writing complex sequential functions.

Symbol


Symbol is a unique and immutable data type that can be used as an identifier for object properties. They are service tools and therefore you hardly have to work with them, but you need to know them. Why do we need a new data type? It is needed so that language developers can add new identifiers or properties of objects without reserving string names for these properties.

So you can create a character property:

 var user = { name: "Alex", [Symbol("password")]: "12hsK3I" } 

To get an array of character objects, use the Object.getOwnPropertySymbols (obj) property;
To gain access anywhere in your code, use the Symbol.for () and Symbol.keyFor () methods.

Source: https://habr.com/ru/post/460741/


All Articles