This publication is the second part of the translation of the article “Introduction to commonly used ES6 features” by Zell Liew, posted here . The translation of the 1st part is here .
Destructuring is a convenient way to extract values from arrays and objects. There are minor differences between the destructurization of arrays and objects, so we consider them separately.
Suppose you have the following object:
const Zell = { firstName: 'Zell', lastName: 'Liew' }
To get firstName
and lastName
from Zell
you need to create two variables, and then assign each variable a value as follows:
let firstName = Zell.firstName; // Zell let lastName = Zell.lastName; // Liew
With destructurization, the creation and assignment of these variables is done in a single line of code. Below is an example of object restructuring:
let { firstName, lastName } = Zell; console.log(firstName); // Zell console.log(lastName); // Liew
When adding curly braces to a variable declaration, an instruction is made to create these variables and then assign Zell.firstName
in firstName
, and Zell.lastName
in lastName
.
Explain what happens under the "hood":
// , : let { firstName, lastName } = Zell; // , ES6 : let firstName = Zell.firstName; let lastName = Zell.lastName;
Now, if the variable name is already taken, then it is impossible to declare the same variable again (especially if you use let
or const
).
The following code does not work:
let name = 'Zell Liew'; let course = { name: 'JS Fundamentals for Frontend Developers' // ... } let { name } = course; // Uncaught SyntaxError:
In such situations, you can rename variables at the same time as destructuring with a colon.
In the example below, the variable courseName
is created and assigned to it course.name
.
let { name: courseName } = course; console.log(courseName); // JS Fundamentals for Frontend Developers // , ES6 : let courseName = course.name;
Note that if you unstructure a variable that is not in the object, then undefined
will be returned.
let course = { name: 'JS Fundamentals for Frontend Developers' } let { package } = course; console.log(package); // undefined
Remember the default settings? You can also write default parameters for unstructured variables. Syntax is similar to function declaration syntax.
let course = { name: 'JS Fundamentals for Frontend Developers' } let { package = 'full course' } = course; console.log(package); // full course
You can even rename variables when specifying default parameters. It is necessary to make a combination of two syntaxes, which will be unusual at first, but you can get used to this:
let course = { name: 'JS Fundamentals for Frontend Developers' } let { package: packageName = 'full course' } = course; console.log(packageName); // full course
This is all related to the destructuring of objects. Now consider the destructuring of arrays.
Destructuring arrays and objects are similar. When working with arrays instead of braces are used square.
With array destructurization:
let [one, two] = [1, 2, 3, 4, 5]; console.log(one); // 1 console.log(two); // 2
If during destructuring the number of variables exceeds the size of the array, the additional variables will be undefined
.
let [one, two, three] = [1, 2]; console.log(one); // 1 console.log(two); // 2 console.log(three); // undefined
When destructurizing an array, only the necessary variables are often extracted. To get the remainder, use the rest statement as follows:
let scores = ['98', '95', '93', '90', '87', '85']; let [first, second, third, ...rest] = scores; console.log(first); // 98 console.log(second); // 95 console.log(third); // 93 console.log(rest); // [90, 87, 85]
Rest operator will be presented in more detail in the next section. Now consider the permutation of variables using array restructuring.
Suppose there are two variables a
and b
.
let a = 2; let b = 3;
You need to rearrange these variables so that a
becomes equal to 3 and b
is equal to 2. In ES5, you would use a temporary third variable to solve this problem:
let a = 2; let b = 3; let temp; // temp = a; // temp 2 a = b; // a 3 b = temp; // b 2
This code works, despite the unclear and confusing logic with the inclusion of a third variable.
With array restructuring in ES6, this is solved in the following way:
let a = 2; let b = 3; // [a, b] = [b, a]; console.log(a); // 3 console.log(b); // 2
This method of variable permutation is much simpler than the previous one.
Next, we consider the destructurization of arrays and objects in functions.
Destructuring can be used literally everywhere, even when declaring functions.
Suppose there is a function that takes an array of values and returns an object with three upper values. Such a function is an analogy of what happens during the destructuring of arrays.
function topThree (scores) { let [first, second, third] = scores; return { first: first, second: second, third: third } }
An alternative way to write such a function is to destruct the scores
when declaring the function. In this case, you will need to write one less line of code. It is also necessary to remember that an array will be passed to the function.
function topThree ([first, second, third]) { return { first: first, second: second, third: third } }
If we can combine default parameters and destructuring when declaring functions, what will be the result of the code below?
function sayMyName ({ firstName = 'Zell', lastName = 'Liew' } = {}) { console.log(firstName + ' ' + lastName); }
First , note that a function takes one argument object. This object is optional and defaults to {}
.
Secondly , an attempt is made to destructurize the variables firstName
and lastName
from the passed object. If such properties are found, they will be used.
As a result, if firstName
or lastName
not defined ( undefined
) in the object, then they will be assigned the values of Zell
and Liew
, respectively.
So, this function displays the following results:
sayMyName(); // Zell Liew sayMyName({firstName: 'Zell'}); // Zell Liew sayMyName({firstName: 'Vincy', lastName: 'Zhang'}); // Vincy Zhang
Next, consider rest and spread.
Rest parameter and spread operator are similar, since both are denoted by three dots. However, they differ in that they perform when used. For this reason, they are differently named and will be considered separately.
In the free interpretation, the rest parameter indicates to take the rest of the data and wrap it in an array. If in detail, a comma-separated list of arguments is converted into an array.
Let's get acquainted with the rest parameter in action. Suppose there is a function add
, which summarizes its arguments:
sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // 55
In ES5, we depend on the arguments
variable every time we deal with a function that accepts an unknown number of variables. The variable arguments
is the array-like Symbol
.
function sum () { console.log(arguments); } sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Arguments
- Symbol
(not an array)
One way to calculate this amount of arguments is to convert it to an array using Array.prototype.slice.call(arguments
), and then loop through each element with such array methods as forEach
or reduce
.
I'm sure you can implement forEach
yourself, so the example below is shown below:
// ES5 function sum () { let argsArray = Array.prototype.slice.call(arguments); return argsArray.reduce(function(sum, current) { return sum + current; }, 0) }
In ES6, with the rest parameter, it is possible to translate comma-separated arguments directly into an array:
// ES6 const sum = (...args) => args.reduce((sum, current) => sum + current, 0); // ES6 function sum (...args) { return args.reduce((sum, current) => sum + current, 0); }
Rest parameter was previously briefly presented in the section on destructuring. Then, from the array, the top three values were unstructured:
let scores = ['98', '95', '93', '90', '87', '85']; let [first, second, third] = scores; console.log(first); // 98 console.log(second); // 95 console.log(third); // 93
If you need to get the rest of the data, we would refer to the rest parameter.
let scores = ['98', '95', '93', '90', '87', '85']; let [first, second, third, ...restOfScores] = scores; console.log(restOfScores); // [90, 97, 95]
If you are confused by something, remember that the rest parameter translates data into an array and appears in the parameters of the functions and during the destructuring of arrays.
Next, consider the spread operator.
Spread operator acts opposite to rest parameter. In a free interpretation, the operator takes an array and expands it into a comma-separated list of arguments.
let array = ['one', 'two', 'three']; // console.log(...array); // one two three console.log('one', 'two', 'three'); // one two three
Spread operator is often used to concatenate arrays in an easy-to-read and understandable way.
Suppose you need to combine the following arrays:
let array1 = ['one', 'two']; let array2 = ['three', 'four']; let array3 = ['five', 'six'];
In ES5, the Array.concat
method is used to concatenate arrays. To combine a set of arrays, a chain is composed as follows:
// ES5 let combinedArray = array1.concat(array2).concat(array3); console.log(combinedArray) // ['one', 'two', 'three', 'four', 'five', 'six'];
In ES6 spread, the operator allows combining arrays into a new array in a way that is easier to read:
// ES6 let combinedArray = [...array1, ...array2, ...array3]; console.log(combinedArray); // ['one', 'two', 'three', 'four', 'five', 'six']
The spread operator can also be used to remove an item from an array without modifying the array. This method is common in Redux. I recommend you watch the video from Dan Abramov to find out how it works.
Extended object literals in ES6 introduce three improvements. These include:
Consider each of them.
Have you noticed that sometimes you write a variable in the property of an object with the same name as the property of the object? This is shown in the following example:
const fullName = 'Zell Liew'; const Zell = { fullName: fullName }
In such situations, would you like to write code shorter?
ES6 extends objects with abbreviations for property values, which means that you can only write a variable if the variable name matches the property name.
It looks like this:
const fullName = 'Zell Liew'; // ES6 const Zell = { fullName } // , ES6: const Zell = { fullName: fullName }
Methods are functions associated with an object property. Below is an example of a method:
const anObject = { aMethod: function () { console.log("I'm a method!~~")} }
An abbreviation for methods in ES6 is that deleting : function
from a method declaration does not break its work:
const anObject = { // ES6 aShorthandMethod (arg1, arg2) {}, // ES5 aLonghandMethod: function (arg1, arg2) {}, }
With this improvement, objects are already getting abbreviations for the method, so I do not recommend using arrow functions when declaring objects, because this breaks the context of this
(go back to the section on arrow functions, if you don’t remember why this happens).
const dontDoThis = { // : arrowFunction: () => {} }
We now turn to the last improvement of objects.
Sometimes there is a need for a dynamic property name when creating objects. Previously, you would have to create an object, and then add the property as follows:
// ES5 const newPropertyName = 'smile'; // const anObject = { aProperty: 'a value' } // anObject[newPropertyName] = ':D'; // anObject['bigger ' + newPropertyName] = 'XD'; // // { // aProperty: 'a value', // 'bigger smile': 'XD' // smile: ':D', // }
In ES6, there is no need for such a “workaround” because It is possible to assign a dynamic property name directly when creating an object. At the same time, it is important to wrap the dynamic property in square brackets:
const newPropertyName = 'smile'; // ES6 const anObject = { aProperty: 'a value', // [newPropertyName]: ':D', ['bigger ' + newPropertyName]: 'XD', } // // { // aProperty: 'a value', // 'bigger smile': 'XD' // smile: ':D', // }
This is all about extended object literals. Next, consider another useful feature: patterned strings.
Working with strings in javascript is an extremely difficult process. We encountered this when creating the announcePlayer function in the section on default parameters. The code below creates spaces with empty lines, which are combined by addition:
function announcePlayer (firstName, lastName, teamName) { console.log(firstName + ' ' + lastName + ', ' + teamName); }
In ES6, this problem is solved by pattern literals (in the specification, they were previously called pattern strings).
To create a template literal, it is necessary to wrap the lines in reverse apostrophes. Inside the reverse apostrophes, a special pointer ${}
is used in which you can write JavaScript code.
Below is an example of how this looks in action:
const firstName = 'Zell'; const lastName = 'Liew'; const teamName = 'unaffiliated'; const theString = `${firstName} ${lastName}, ${teamName}`; console.log(theString); // Zell Liew, unaffiliated
Thus, it became possible to make various combinations using template literals, which resembles the use of a template engine.
The most useful feature of patterned literals is the ability to create multi-line strings. Below is an example:
const multi = `One upon a time, In a land far far away, there lived a witich, who could change night into day`;
Such lines can be used to create HTML elements in JavaScript code (this is not the best way to create HTML elements, but better than creating them one by one separately).
const container = document.createElement('div'); const aListOfItems = `<ul> <li>Point number one</li> <li>Point number two</li> <li>Point number three</li> <li>Point number four</li> </ul>`; container.innerHTML = aListOfItems; document.body.append(container);
Another feature of template literals are tags. Tags are functions that allow you to manipulate the template literal to replace any string.
Below is an example:
const animal = 'lamb'; // const tagFunction = () => { // } // tagFunction const string = tagFunction `Mary had a little ${animal}`;
To be honest, despite the fact that the template tags make an impression, I still have not had a situation to apply them. In order to study them in more detail, I recommend reading the material on MDN.
These were all the features of ES6 that I use on a regular basis. It is definitely worth spending a bit of your time and study them in order to understand what others are writing around.
Source: https://habr.com/ru/post/341500/
All Articles