var a = 2; (function IIFE(){ var a = 3; console.log( a ); // 3 })(); console.log( a ); // 2
{ .. }
. Instead of using the var
operator that we used to declare the variables of the internal (or global) scope, we can use let
to declare a block:
var a = 2; { let a = 3; console.log( a ); // 3 } console.log( a ); // 2
{ ... }
. I recommend that you put let
declarations at the very beginning of a block, and if you have more than one declaration, use only one let
statement.
{
, so that you clearly emphasize for which block these variables are intended:
{ let a = 2, b, c; // .. }
let
statement, and it is called a let-block:
// ES6 let (a = 2, b, c) { // .. }
let
similar to var
is not explicit , as it applies to the entire scope block.
let (..) { .. }
was not accepted in ES6. Perhaps in the next updates of ES6, we will see this form, but for now the first example is the best we have.
let
statement, let's consider the following example:
let a = 2; if (a > 1) { let b = a * 3; console.log( b ); // 6 for (let i = a; i <= b; i++) { let j = i + 10 console.log( j ); } // 12 13 14 15 16 let c = a + b; console.log( c ); // 8 }
if
block, and which variables only in the for
loop?
if
block contains the variables a
and b
block scope, and for
variables i
and j
block scope.
i
not added to the scope of the if
block?
c
;
var
operator kind of " attaches " a variable to the scope and initializes it when the function is entered before it is executed, regardless of where it was declared. This phenomenon is known as elevation . The let
statement also attaches a variable to the scope before it is executed, but does not initialize it when entering the function, which, if attempted to access such a variable, before it is declared / initialized, will result in an error.
{ console.log( a ); // undefined console.log( b ); // ReferenceError! var a; let b; }
let b;
- quite enough. It is assumed that a variable which was not assigned a value during the declaration will be initialized to the value undefined
, the default. let b;
same as let b = undefined;
. But I repeat - before, let b;
will not be executed, use this variable, you can not.
typeof
behavior with tdz variables:
{ if (typeof a === "undefined") { console.log( "cool" ); } if (typeof b === "undefined") { // ReferenceError! // .. } // .. let b; }
not declared, the only safe way to check it for existence is using the typeof
operator. But this was not the case with the variable b
, which throws an exception, since it was declared much lower using the let
operator.
let
be at the very top of the block. This will save you from the headache of refactoring, eliminating unexplained errors, make the code more understandable and predictable.
let
statement and block scope, we'll talk in chapter 3.
let
statement is how it behaves with the for
loop.
var funcs = []; for (let i = 0; i < 5; i++) { funcs.push( function(){ console.log( i ); } ); } funcs[3](); // 3
let i
expression in the for
header declares a new variable not for the entire cycle, but for each individual iteration. The same is true for the circuit inside the loop. In fact, the code behaves exactly as expected.
var i
instead of let i
, then you would get 5 instead of 3 as a result of doing this, since in this case the closure will be common to all iterations.
var funcs = []; for (var i = 0; i < 5; i++) { let j = i; funcs.push( function(){ console.log( j ); } ); } funcs[3](); // 3
j
variable for each iteration. I prefer the first option, which, of course, less obvious, but not so much as to abandon it.
const
.
{ const a = 2; console.log( a ); // 2 a = 3; // TypeError! }
undefined
, therefore if you need such a value, then you will have to manually assign it - const a = undefined;
.
{ const a = [1,2,3]; a.push( 4 ); console.log( a ); // [1,2,3,4] a = 42; // TypeError! }
let
or var
.
{ foo(); // ! function foo() { // .. } } foo(); // ReferenceError
let
declaration, which we cannot work with before such a variable is initialized, in this case the TDZ error does not occur.
if (something) { function foo() { console.log( "1" ); } } else { function foo() { console.log( "2" ); } } foo(); // ??
foo()
function is "2"
- regardless of the value of the variable something
, since, thanks to the elevation, the working function will be the second.
ReferenceError
.Source: https://habr.com/ru/post/257511/