var
keyword has not gone away, mean not only new opportunities, but also the emergence of new questions. When to use the keywords let
and const
? How do they behave? In what situations is the var
keyword still relevant? The material, the translation of which we are publishing today, is aimed at studying the problem of the scope of variables in JavaScript. var myVar = 1; function setMyVar() { myVar = 2; } setMyVar(); console.log(myVar);
console.log
method display? The answer to this question will not surprise anyone: it will output 2
. The variable myVar
declared outside of any function, which tells us that it is declared in the global scope. Therefore, any function declared in the same scope can refer to myVar
. In fact, if we are talking about code executed in the browser, functions declared in other files connected to the page will even have access to this variable. function setMyVar() { var myVar = 2; } setMyVar(); console.log(myVar);
console.log
display now? In fact, nothing, since this variable is not declared, and when you try to access it, you will get a message about the raw ReferenceError
error. This is because the variable, using the var
keyword, is declared inside the function. As a result, the scope of this variable is limited to the internal scope of the function. It can be accessed in the body of this function; functions embedded in this function can work with it, but it is not available from the outside. If we need a certain variable to be used by several functions that are on the same level, we need to declare this variable in the same place where these functions are declared, that is, one level above their internal scope. function varTest() { for (var i = 0; i < 3; i++) { console.log(i); } console.log(i); } varTest();
i
will be displayed: 0
, 1
and 2
. After the cycle ends, the program continues to run. Now we are trying to access the same counter variable that was declared in the for
loop, outside of this loop. What will come of it?i
outside the loop, the console will get 3, since the var
keyword is valid at the function level. If you declare a variable using var
, then you can access it in a function after exiting the construction where it was declared. function doSomething() { var myVar = 1; if (true) { var myVar = 2; console.log(myVar); } console.log(myVar); } doSomething();
2
and 2
. We declare the variable, initialize it with the number 1, and then try to override the same variable inside the if
expression. Since these two declarations exist in the same scope, we cannot declare a new variable with the same name, even though we obviously want to do just that. As a result, the first variable is overwritten inside an if
expression.var
keyword. The scope of variables declared using it is too large. This can lead to inadvertent overwriting of data and other errors. Large scopes often lead to sloppy programs. In general, a variable should have a scope that is limited by its needs, but not exceeding them. It would be good to be able to declare variables whose scope is not as large as when using var
, which would allow, if necessary, to use more stable and better error-protected software constructs. In fact, ECMAScript 6 provides us with such opportunities.var
, with a scope and some other features. These are the let
and const
keywords. Both that and another gives us a so-called block scope. This means that when used, the scope can be limited to a block of code, such as a for
loop or an if
expression. This gives the developer more flexibility in the choice of scopes of variables. Consider new keywords.let
keyword is very similar to var
, the main difference is the limited scope of variables declared with it. Rewrite one of the above examples, replacing var
with let
: function doSomething() { let myVar = 1; if (true) { let myVar = 2; console.log(myVar); } console.log(myVar); } doSomething();
2
and 1
will go to the console. This happens because the if
expression specifies a new scope for a variable declared with the let
keyword. This leads to the fact that the second declared variable is a completely independent entity, not connected with the first one. You can work with them independently. However, this does not mean that nested blocks of code, such as our if
expression, are completely cut off from the variables declared with the let
keyword in the scope in which they themselves are located. Take a look at the following code: function doSomething() { let myVar = 1; if (true) { console.log(myVar); } } doSomething();
1
will appear in the console. The code inside the if
expression has access to the variable we created outside of it. Therefore, he displays its value in the console. What happens if you try to shuffle the scopes? For example, do this: function doSomething() { let myVar = 1; if (true) { console.log(myVar); let myVar = 2; console.log(myVar); } } doSomething();
console.log
will display 1
, but in fact, when you try to execute this code, a ReferenceError
error will appear, which tells us that the myVar
variable for this scope is not defined or not initialized (the text of this error differs in different browsers). In JavaScript, there is such a thing as raising variables to the upper part of their scope. That is, if a variable is declared in some scope, JavaScript reserves space for it even before the command for its declaration is executed. How exactly this happens is different when using var
and let
. console.log(varTest); var varTest = 1; console.log(letTest); let letTest = 2;
var
keyword, will output undefined
- that is, what will be written to this variable. The second command, which tries to access a variable that will later be declared using the let
keyword, will issue a ReferenceError
and tell us that we are trying to use the variable before it is declared or initialized. What's the matter?var
keyword are initialized to undefined
within their scope, even if they are accessed before they are declared. The main problem here is that the value undefined
in a variable does not always indicate that the variable is attempted to be used before it is declared. Take a look at the following example: var var1; console.log(var1); console.log(var2); var var2 = 1;
var1
and var2
declared differently, both console.log
calls will display undefined
. The point here is that the variables declared with var
but not initialized are automatically written to the value undefined
. In this case, as we have said, variables declared with var
, which are accessed before they are declared, also contain undefined
. As a result, if something goes wrong in such a code, it will not be possible to understand what exactly is the source of the error — the use of an uninitialized variable or the use of a variable prior to its declaration.let
keyword is reserved in their block, but before they are declared they fall into the Temporal Dead Zone (TDZ). This leads to the fact that they, before their declaration, cannot be used, and an attempt to access such a variable leads to an error. However, the system knows the exact cause of the problem and reports this. This is clearly seen in this example: let var1; console.log(var1); console.log(var2); let var2 = 1;
console.log
will display undefined
, and the second will cause a ReferenceError
error, telling us that the variable has not yet been declared or initialized.var
appears with undefined
, we do not know the reason for this behavior of the program. A variable can either be declared and uninitialized, or it may not yet be declared in this scope, but will be declared in code that is located below the command to access it. When using the let
keyword, we can understand what is happening, and this is much more useful for debugging.const
keyword is very similar to let
, but they have one important difference. This keyword is used to declare constants. Values of constants after their initialization cannot be changed. It should be noted that this applies only to the values of primitive types, water strings or numbers. If a constant is something more complicated, for example, an object or an array, the internal structure of such an entity can be modified, you cannot just replace it with another. Take a look at the following code: let mutableVar = 1; const immutableVar = 2; mutableVar = 3; immutableVar = 4;
TypeError
error. This is how constants behave, but, as already mentioned, the objects with which constants are initialized can be changed, they can undergo mutations, which can lead to surprises . const myButton = document.querySelector('#my-button');
const
keyword goes not only along the path of improvements in the scope of visibility, but also along the path of limiting the possibility of modifying the values of constants declared using this keyword. Remember how we talked about the fact that a variable should have exactly the scope that it needs. This idea can be continued by putting forward a recommendation that the variable should only have the opportunity to change, which is necessary for proper work with it, and nothing more. Here is a good material on the topic of immunity, from which an important conclusion can be drawn, according to which the use of immutable variables forces us to think more carefully about our code, which leads to an improvement in the purity of the code and to a decrease in the number of unpleasant surprises arising from its work.let
and const
, I basically applied let
, resorting to const
only when writing a new value to a variable declared with let
could harm the program. But, learning more about programming, I changed my mind on this issue. Now my main tool is const
, and let
me use let
only when the value of a variable needs to be rewritten. It makes me think about whether it is really necessary to change the value of some variable. In most cases, this is not necessary.let
and const
promote a more responsible approach to programming. Are there any situations in which the var
keyword is still needed? Yes, there are. There are several situations in which this keyword is still useful to us. Think about what we are going to talk about before changing var
to let
or const
.var
keyword have one very important feature missing from let
and const
. Namely, we are talking about the fact that this keyword is supported by absolutely all browsers. Although the let and const browsers support is very good, however, there is a risk that your program will get into a browser that does not support them. In order to understand the consequences of such an incident, you need to consider how browsers treat unsupported JavaScript code, as opposed to, for example, how they react to incomprehensible CSS code.let
, and the browser does not support this keyword, then your JS code will simply not work there. It will not be - that's all. Considering the fact that JavaScript is one of the important components of the modern web, this can be a very serious problem if you need your programs to work in outdated browsers.let
and const
, then a similar question will have to be put differently: “In which browsers will our site not work?”. And this is much more serious than talking about whether or not to use display: flex
. For most websites, the number of users with outdated browsers will not be large enough to be worth worrying about. However, if we are talking about something like an online store, or sites whose owners buy advertising, this can be a very important consideration. Before using new opportunities in such projects, assess the level of risk.let
, const
and other new features of ES6 while doing this, one of the solutions to this problem is to use a JavaScript transpiler like Babel . Transporters provide a translation of the new code into what will be clear to the old browsers. Using Babel, you can write modern code that uses the latest features of the language, and then convert it to code that older browsers can perform.var
, . . : var myVar = 1; function myFunction() { var myVar = 2; // , myVar ! }
myVar
, , . , . , , , , . , . var
. var myVar = 1; function myFunction() { var myVar = 2; console.log(myVar); // 2 console.log(window.myVar); // 1 }
var
, window
. let
const
. , JS- , (, , ) , . let myGlobalVars = {}; let myVar = 1; myGlobalVars.myVar = myVar; function myFunction() { let myVar = 2; console.log(myVar); // 2 console.log(myGlobalVars.myVar); // 1 }
var
, , , , , .var
.var
, const
. - (, , ) — let
.let
const
, ECMAScript 6, ( ) - -. , , , . , - , «» «» , , let
const
, .const
var
, let
, , , ?Source: https://habr.com/ru/post/420359/
All Articles