JavaScript context views

Hello again! We already wrote that at the end of September in OTUS a new stream of the course "Fullstack JavaScript Developer" will start. In anticipation of the start of classes, we continue to share with you copyright articles prepared especially for students of the course. Today we’ll look at context types in JavaScript. Go.



Article author: Pavel Yakupov








The purpose of this article is for the reader to understand the basic concepts of scopes that are used in JavaScript.


Scope is one of the most important things in JavaScript (and has a place in most modern programming languages). Scope is associated with the long life of a variable or function, access, the visibility of variables, and some other things.



Why do we need this scope at all?



The scope in programming languages ​​performs the following functions:

Security (encapsulation) - variables and functions are available only when they are needed.

Eliminates the conflict of variable names. The presence of scopes allows you not to “pile” all the variables into one heap, simulating namespaces (namespace).

Reuse of code - the written code can then be used, avoiding "extraneous" effects.



Types of Scopes



At the simplest level, in JavaScript there are two areas of visibility - local and global.



In this article, we will also touch on such a scope as lexical and block.



Global scope



When you open a document in JavaScript and start writing code, you fall into the global scope.



Everything that is created in the global scope - variables, functions - are accessible from anywhere in the program. Also, global variables are available all the time your application is running and are deleted only when the program finishes its work.



Many newcomers at first use global variables too often - this is somewhat easier to program, but this is considered bad practice, and often leads to unstable programs that ultimately use far more memory than they actually need. After all, if the variables were encapsulated reliably inside the functions in which they are used, at the end of the function, they would be deleted from memory using the Garbage collector, and stop occupying client memory, which is not infinite.



Local scope



Variables that are declared locally are only available in the scope where they were declared.



The easiest way to create a new scope is to create a new function. A variable created inside a function is accessible only from the inside. In addition, the local scope can be obtained using the block scope (will be discussed below).



function foo(){ let x = 15; } //console.log(x); error { let y = 14; } // console.log(y);  error { var z = 13; } console.log(z); // var   , //        // -  13
      
      





Lexical scope



So what is lexical scope? In simple terms, this is the ability of an internal function to access an external scope. Here it is worth turning to the practice of closures. You can probably write a couple more articles about them, but I will quickly give you one classic example:



 sum(5)(5) //    ? function sum(a){ var add = function(b){ return a+b; } return add; } console.log(sum(5)(5)); // 10   //     
      
      





Block scope



So far, we have only discussed scopes that are related to the operation of functions and curly braces {}, and we discussed the differences in the operation of var and let only indirectly.



How does the var directive work? When a variable is declared using it in the global scope, the variable name is assigned as a property to the global window object (if we mean the browser) and remains there all the time the program runs. At the same time, as a block scope, such as {} (and if, for, while, and all the others are included quite logically).



In addition, there is another feature of let and const - declared in one scope, then they cannot be declared again in the same scope (well, the dissatisfaction of the interpreter looks quite logical here).



 let x = 15; console.log(x); //   { let x = 16; //       console.log(x) //          let x = 17; //        ,         }
      
      





new Function



Features of scope when declaring a new function as "new Function". This option to create a function is rarely used, but sometimes it may be required.

Syntax Example:



 //let newFunc = new Function([arg1, arg2…argN], functionBody); let mult = new Function('a', 'b', 'return a * b'); console.log(mult(3,4));
      
      





Usually, a function remembers where it was born (Lexical Environment), but when a function is created using the new Function construct, it is not the variables surrounding it that are written into its environment variables, as in a normal situation, but only declared globally.



 //   ,      ()()     let a = 3; function outerFunc() { var a = 2; var func = new Function('console.log(a*a)'); return func; } outerFunc()(); // 9,    window
      
      





Hoisting (raising variables)



Discussing the scope, we could not help addressing the topic of raising the scope of variables. The interpreter that reads the code actually reads it two times: it reads the functions declared as function declaraton, and reads global variables declared global using the var variable. However, the variables are recorded not by their declared values, but by the value undefined.



 console.log(x); // undefined var x = 15; console.log(y);// error let y = 13;
      
      





Let this topic only indirectly relate to areas of visibility, but sometimes this knowledge can come in handy.



Thanks to all! I hope this article was useful to someone!







Useful links:



developer.mozilla.org/en-US/docs/Glossary/Scope

developer.mozilla.org/en/docs/Web/JavaScript/Closures

2ality.com/2015/02/es6-scoping.html

learn.javascript.ru/new-function

habr.com/en/company/otus/blog/466873



All Articles