📜 ⬆️ ⬇️

12 JavaScript Concepts to Know

JavaScript is a complex language. If you, at any level, are engaged in JavaScript development, it means that it is vital for you to understand the basic concepts of this language. The article, the translation of which we are publishing today, discusses the 12 most important JavaScript concepts. Of course, a JavaScript developer needs to know much more, but without what we are going to talk about today, he definitely cannot do.



1. Variables storing values ​​and references


Understanding exactly how variable values ​​are assigned in JavaScript is extremely important for those who want to write properly working code. Failure to understand this mechanism leads to writing programs in which the values ​​of variables can inadvertently change.

JavaScript, if a certain entity has one of the primitive types (in particular, these are the types Boolean , null , undefined , String and Number ), always works with the value of this entity. That is, the value is written to the corresponding variable. If we are talking about an object (for example, these are Object , Array , Function types), then when assigning it to a variable, a reference to it is written to it, the address where it is located in memory.
')
Consider an example. In the following code snippet, a string is written to the var1 variable. After that, the variable var2 recorded the value of the variable var1 . Since the variable var1 is of the primitive type ( String ), then a copy of the string present in var1 var2 be written to var1 . This allows you to treat var2 as a variable that is completely independent of var1 , although it stores the same value as var1 . Writing var2 new value does not affect var1 .

 let var1 = 'My string'; let var2 = var1; var2 = 'My new string'; console.log(var1); // 'My string' console.log(var2); // 'My new string' 

Now consider an example of working with objects.

 let var1 = { name: 'Jim' } let var2 = var1; var2.name = 'John'; console.log(var1); // { name: 'John' } console.log(var2); // { name: 'John' } 

As you can see, here we are working with the var2 variable, and what happens to it is reflected in the var1 variable as they store a reference to the same object. It is easy to imagine what this might lead to in real code if someone decides that the variables that store objects behave in the same way as variables that store values ​​of primitive types. This is especially unpleasant, for example, in cases where a function is created that is designed to work with the object value passed to it, and this function unintentionally changes this value.

2. Closures


A closure is an important JavaScript design pattern that allows you to organize secure work with variables. In the following example, the createGreeter() function returns an anonymous function that has access to the greeting argument provided to the source function, which contains the string Hello . The link to this anonymous function is written to the variable sayHello . After this, how many times we call the sayHello() function, it will always have access to the value of greeting . In this case, access to greeting will be only for an anonymous function, the link to which is recorded in sayHello .

 function createGreeter(greeting) { return function(name) {   console.log(greeting + ', ' + name); } } const sayHello = createGreeter('Hello'); sayHello('Joe'); // Hello, Joe 

It was a very simple example. If we consider something closer to the real world, then we can imagine, for example, a function for connecting to a certain API (let's call it apiConnect() ), which, when first called, is passed the API access key. This function, in turn, returns an object containing several methods that use the API access key passed to apiConnect() . In this case, the key is stored in the closure and it is no longer necessary to mention it when calling these methods.

 function apiConnect(apiKey) { function get(route) {   return fetch(`${route}?key=${apiKey}`); } function post(route, params) {   return fetch(route, {     method: 'POST',     body: JSON.stringify(params),       headers: {         'Authorization': `Bearer ${apiKey}`       }     }) } return { get, post } } const api = apiConnect('my-secret-key'); //     API     api.get('http://www.example.com/get-endpoint'); api.post('http://www.example.com/post-endpoint', { name: 'Joe' }); 

3. Destructuring assignment


If you have not yet used destructive assignment in JavaScript, then it is time to fix it. Destructive assignment is a common way to retrieve object properties using a neat syntactic language construct.

 const obj = { name: 'Joe', food: 'cake' } const { name, food } = obj; console.log(name, food); // 'Joe' 'cake' 

If the extracted properties need to be assigned names that differ from those they have in the object, you can do this:

 const obj = { name: 'Joe', food: 'cake' } const { name: myName, food: myFood } = obj; console.log(myName, myFood); // 'Joe' 'cake' 

In the following example, destructuring is used to accurately transfer the values ​​stored in the properties of the person object to the introduce() function. This is an example of how this construct is used when declaring a function to extract data from the object passed to it with parameters. By the way, if you are familiar with React, then you probably have already seen this.

 const person = { name: 'Eddie', age: 24 } function introduce({ name, age }) { console.log(`I'm ${name} and I'm ${age} years old!`); } console.log(introduce(person)); // "I'm Eddie and I'm 24 years old!" 

4. Operator spread


The spread operator is a rather simple construction that may seem incomprehensible to an unprepared person. In the following example, there is a numeric array, the maximum value stored in which we need to find. We want to use the Math.max() method for this, but it cannot work with arrays. It takes independent numerical values ​​as arguments. In order to extract its elements from an array, we use the spread operator, which looks like three points.

 const arr = [4, 6, -1, 3, 10, 4]; const max = Math.max(...arr); console.log(max); // 10 

5. Operator rest


The rest operator allows you to convert any number of arguments passed to the function into an array.

 function myFunc(...args) { console.log(args[0] + args[1]); } myFunc(1, 2, 3, 4); // 3 

6. Array methods


Array methods often give the developer convenient tools to beautifully solve a wide variety of data conversion tasks. I sometimes answer questions on StackOverflow. Among them often come across those that are devoted to something like this or that way of working with arrays of objects. In such situations, array methods are especially useful.

Here we consider several such methods, united according to the principle of their similarity with each other. It should be noted that here I will tell you far from all methods of arrays. You can find their full list on MDN (by the way, this is my favorite JavaScript reference).

MapMaphods map (), filter () and reduce ()


The array methods map() , filter() and reduce() allow you to transform arrays or reduce arrays to a single value (which can be an object).

The map() method returns a new array containing the transformed values ​​of the array being processed. How exactly they will be transformed is specified in the function passed to this method.

 const arr = [1, 2, 3, 4, 5, 6]; const mapped = arr.map(el => el + 20); console.log(mapped); // [21, 22, 23, 24, 25, 26] 

The filter() method returns an array of elements, checking which values ​​the function passed to this method returned true .

 const arr = [1, 2, 3, 4, 5, 6]; const filtered = arr.filter(el => el === 2 || el === 4); console.log(filtered); // [2, 4] 

The reduce() method returns a value that represents the result of processing all the elements of the array.

 const arr = [1, 2, 3, 4, 5, 6]; const reduced = arr.reduce((total, current) => total + current); console.log(reduced); // 21 

FindMethods find (), findIndex () and indexOf ()


The array methods find() , findIndex() and indexOf() easy to confuse with each other. Below are explanations to help you understand their features.

The find() method returns the first element of the array that matches the specified criteria. This method, having found the first suitable element, does not continue searching the array.

 const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; const found = arr.find(el => el > 5); console.log(found); // 6 

Please note that in our example, all the elements of the array that follow the one that contains the number 5, but only the first matching element are returned, meet the specified criteria. This method is very useful in situations in which, using for for searching and analyzing arrays with for loops, such loops, when a necessary element is detected in the array, are interrupted using the break instruction.

The findIndex() method is very similar to find() , but instead of returning the first matching element of the array, it returns the index of such an element. To better understand this method, take a look at the following example, which uses an array of string values.

 const arr = ['Nick', 'Frank', 'Joe', 'Frank']; const foundIndex = arr.findIndex(el => el === 'Frank'); console.log(foundIndex); // 1 

The indexOf() method is very similar to the findIndex() method, but it takes as an argument not a function, but an ordinary value. You can use it if you do not need complex logic when searching for the desired element of the array.

 const arr = ['Nick', 'Frank', 'Joe', 'Frank']; const foundIndex = arr.indexOf('Frank'); console.log(foundIndex); // 1 

PushPush (), pop (), shift () and unshift () methods


The push() , pop() , shift() and unshift() are used to add new elements to arrays and to extract elements already existing in them from arrays. In this case, the work is performed with elements located at the beginning or at the end of the array.

The push() method allows you to add elements to the end of an array. It modifies the array, and, upon completion of the work, returns the element added to the array.

 let arr = [1, 2, 3, 4]; const pushed = arr.push(5); console.log(arr); // [1, 2, 3, 4, 5] console.log(pushed); // 5 

The pop() method removes the last element from an array. It modifies the array and returns the element removed from it.

 let arr = [1, 2, 3, 4]; const popped = arr.pop(); console.log(arr); // [1, 2, 3] console.log(popped); // 4 

The shift() method removes the first element from the array and returns it. It also modifies the array for which it is called.

 let arr = [1, 2, 3, 4]; const shifted = arr.shift(); console.log(arr); // [2, 3, 4] console.log(shifted); // 1 

The unshift() method adds one or more elements to the beginning of the array. It, again, modifies the array. At the same time, unlike the three other methods considered here, it returns the new length of the array.

 let arr = [1, 2, 3, 4]; const unshifted = arr.unshift(5, 6, 7); console.log(arr); // [5, 6, 7, 1, 2, 3, 4] console.log(unshifted); // 7 

SlSlice () and splice () methods


These methods are used to modify the array or to return some part of the array.

The splice() method changes the contents of an array, deleting existing elements or replacing them with other elements. He can also add new elements to the array. This method modifies the array.

The following example, if we describe it in ordinary language, looks like this: you need, in the position of array 1 , delete 0 elements and add an element containing b .

 let arr = ['a', 'c', 'd', 'e']; arr.splice(1, 0, 'b') 

The slice() method returns a shallow copy of the array containing its elements, starting at the specified starting position and ending at the position preceding the specified ending position. If, when calling it, only the initial position is specified, it will return the entire array starting from this position. This method does not modify the array. It only returns the part of this array described when it is called.

 let arr = ['a', 'b', 'c', 'd', 'e']; const sliced = arr.slice(2, 4); console.log(sliced); // ['c', 'd'] console.log(arr); // ['a', 'b', 'c', 'd', 'e'] 

Sort sort method ()


The sort() method sorts an array according to the condition specified by the function passed to it. This function takes two elements of the array (for example, they can be represented as parameters a and b ), and comparing them returns if the elements are not to be interchanged, 0 if a needs to be put at a lower index than b is a negative number, and if b to be put at a lower index than a is a positive number.

 let arr = [1, 7, 3, -1, 5, 7, 2]; const sorter = (firstEl, secondEl) => firstEl - secondEl; arr.sort(sorter); console.log(arr); // [-1, 1, 2, 3, 5, 7, 7] 

If you cannot, having familiarized yourself with these methods for the first time, remember them - no problem. The most important thing is that you now know what standard array methods can do. Therefore, if you cannot recall at once the features of a particular method, what you know about it will allow you to quickly find what you need in the documentation.

7. Generators


JavaScript generators are declared using the asterisk symbol. They allow you to specify what value will be returned when you next call the next() method. Generators can be designed to return a limited number of values. If a similar generator returned all such values, then the next call to next() will return undefined . Generators designed to return an unlimited number of values ​​using cycles can also be created.

Here is a generator designed to return a limited number of values:

 function* greeter() { yield 'Hi'; yield 'How are you?'; yield 'Bye'; } const greet = greeter(); console.log(greet.next().value); // 'Hi' console.log(greet.next().value); // 'How are you?' console.log(greet.next().value); // 'Bye' console.log(greet.next().value); // undefined 

But the generator is designed to return an infinite number of values ​​through a cycle.

 function* idCreator() { let i = 0; while (true)   yield i++; } const ids = idCreator(); console.log(ids.next().value); // 0 console.log(ids.next().value); // 1 console.log(ids.next().value); // 2 //   ... 

8. Operators check equality (==) and strict equality (===) values


It is extremely important for any JS developer to understand the difference between the equality ( == ) and strict equality ( === ) operators. The fact is that the operator == , before comparing values, performs the conversion of their types (which can lead to strange, at first glance, consequences), and the operator === does not perform type conversion.

 console.log(0 == '0'); // true console.log(0 === '0'); // false 

9. Comparison of objects


I occasionally have to see how newcomers to JS programming make the same mistake. They are trying to directly compare objects. The variables in which objects are “stored” contain references to them, not the objects themselves.

So, for example, in the following example, objects look the same, but when we compare them directly, we are told that the objects are different, since each of the variables contains a link to its own object and these links are not equal to each other.

 const joe1 = { name: 'Joe' }; const joe2 = { name: 'Joe' }; console.log(joe1 === joe2); // false 

In the following example, it turns out that joe1 is equal to joe2 since both variables store a reference to the same object.

 const joe1 = { name: 'Joe' }; const joe2 = joe1; console.log(joe1 === joe2); // true 

One of the methods of present comparison of objects consists in their preliminary conversion to the format of JSON strings. True, this approach has one problem, which is that the resulting string representation of the object does not guarantee a certain order of its properties. A more reliable way to compare objects is to use a special library containing tools for in-depth comparison of objects (for example, this is the isEqual () method of the lodash library).

In order to better understand the subtleties of comparing objects and realize the possible consequences of writing references to the same objects in different variables, take a look at the first JS concept discussed in this material.

10. Callback Functions


Callback functions are a fairly simple JavaScript concept, with which beginners sometimes have difficulty. Consider the following example. Here, the console.log function (exactly like this - without parentheses) is passed to the myFunc() function as a callback function. This function sets the timer, upon triggering of which console.log() is called and the string passed to the myFunc() function is output to the console.

 function myFunc(text, callback) { setTimeout(function() {   callback(text); }, 2000); } myFunc('Hello world!', console.log); // 'Hello world!' 

11. Promises


After you learn the callback functions and start using them everywhere, you can find yourself in the so-called “callback hell” very soon. If you really are there - take a look at the promises. Asynchronous code can be wrapped in promis, and, after its successful execution, inform the system about the successful resolution of promis by calling the appropriate method, and if something goes wrong, call the method indicating this and reject promis. To process the results returned by the promis, use the then() method, and for error handling, the catch() method.

 const myPromise = new Promise(function(res, rej) { setTimeout(function(){   if (Math.random() < 0.9) {     return res('Hooray!');   }   return rej('Oh no!'); }, 1000); }); myPromise .then(function(data) {   console.log('Success: ' + data);  })  .catch(function(err) {   console.log('Error: ' + err);  }); //  Math.random()  , ,  0.9,    : // "Success: Hooray!" //  Math.random()  , ,  0.9,  0.9,    : // "Error: On no!" 

12. Async / await construction


After you work with promises, you may well want something more. For example - to master the construction of async / await. It is a “syntactic sugar” for promis. In the following example, we create, using the async , an asynchronous function, and in it, using the await keyword, we organize the waiting for the promise to greeter .

 const greeter = new Promise((res, rej) => { setTimeout(() => res('Hello world!'), 2000); }) async function myFunc() { const greeting = await greeter; console.log(greeting); } myFunc(); // 'Hello world!' 

Results


If what we were talking about here was unfamiliar to you before, then you, most likely, at least a little, but grew above yourself after reading this article. If you didn’t find anything new here, then you want to hope that this material has given you the opportunity to practice and strengthen your knowledge of JavaScript.

Dear readers! What other JavaScript concepts would you add to this article?

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


All Articles