Let
It is well known that the keyword declaring a variable is only var before ES6. var declaring a variable is either global or function-level, not block-level.
varA=1; Console.log (a); //1Console.log (WINDOW.A);//1
functionTest () {varb=2; functionprint () {Console.log (A, b); } print ();} Test (); //1 2Console.log (b);//uncaught referenceerror:b is not defined
for(vari=0;i<=10;i++){ varSum=0; Sum+=i;} Console.log (i); // OneConsole.log (sum);//10 declares I and sum inside the for loop, which can be used as a jump out of a for loop.
Take a look at the chestnut below:
HTML:<ul> <Li>0</Li> <Li>1</Li> <Li>2</Li> <Li>3</Li></ul>
function () { var aLi = document.getelementsbytagname (' li '); for (var i=0;i<ali.length;i++) { function() { alert (i); }; }
This is a very classic pen test, but also many beginners often make mistakes and can not find a reason for a piece of code. The effect is to click on a different <li> tag, alert out its corresponding index value, but in fact, after the code runs, we will find that no matter which <li> tag is clicked, alert out of the I is 4. Because after executing the for loop, the value of I has become 4, and when I click the <li> tag, the I Value of alert is 4. Before ES6, most people would choose to use closures to solve this problem, and today we use the LET-ES6 provided to solve this problem. Then let's look at the magic of Let.
function () { var aLi = document.getelementsbytagname (' li '); for (Let i=0;i<ali.length;i++) { function() { alert (i); } }; }
Do you see any difference? The mystery is in the For loop. var i=0 becomes let i=0, we solve this problem only by changing one keyword, and also avoid problems such as memory leaks that can be caused by using closures.
The Let of the For loop header in the code above not only binds I to the block for the For loop, but in fact it rebind it to each iteration of the loop, ensuring that the value is re-assigned at the end of the previous loop iteration.
Let's take a look at the Magic keyword of let in the back.
The Let keyword can bind a variable to any scope in which it resides (usually inside {..}). In other words, let's declare the variable implicitly where the block scope is located. ----"JavaScript you don't Know" P32
The code above can be used in another way to illustrate the behavior of rebinding at each iteration :
function () { var aLi = document.getelementsbytagname (' li '); for (Let i=0;i<ali.length;i++) { = i; function () { alert (j); }} ; }
Another point to note here is that the loop has a special aspect, that is, the loop for
statement is part of a parent scope, and the inside of the loop body is a separate child scope.
This is a good way to understand the meaning of the above code. Each time the loop body executes, the let declaration of the variable J is saved from the parent scope (the loop block) to its own block-level scope, because the block-level scope of the variables are not affected by external interference, so each loop body generated by the block-level scope of each other independent, each holding their own J value.
Take a look at letand thevarsome similarities and differences..
1. Function scope vs block-level scope
functionvartest () {varx = 31; if(true) { varx = 71;//same variable!Console.log (x);// in} console.log (x); // in}functionLettest () {Let x= 31; if(true) {Let x= 71;//different variableConsole.log (x);// in} console.log (x); // to}
It can be seen that the re-declaration of x in the If judgment of the Lettest function does not affect code outside the if code block, whereas the Vartest function is declared with Var. This is because the variables that let declares are valid only in blocks of code (usually the block of code formed by {}).
2. Variable elevation vs temporary Dead Zone
As we all know, the variables declared by VAR will have the function of variable promotion, as follows
Console.log (a); // 1 var a=1; Console.log (b); // undefined var b;
As can be seen, although the code in the console call a before, declare a after, but because in JS, the function and the declaration of the variable will be promoted to the top of the function, that is, the (var declared) variable can be used before the declaration.
Then, using Let,const (which is mentioned later) the declared variable does not have a variable elevation.
// uncaught referenceerror:foois isn't defined let Foo = 2// uncaught referenceerror:foo1 is Not definedlet foo1;
ES6 explicitly states that if a command is present in a chunk, the variables declared by the block on those commands form a closed scope from the outset. If you use these variables before the declaration, you will get an error. So within the code block, the variable is not available until the variable is declared with the Let command. This is syntactically called a "temporary Dead zone" (Temporal Dead Zone, abbreviated as TDZ).
In short, the essence of a temporary dead zone is that, as soon as one enters the current scope, the variable to be used already exists, but is not available and can only be obtained and used until the line of code that declares the variable appears.
Note: "Temporary Dead zone" also means that typeof is no longer a completely safe operation, because it will make typeof error.
3, let does not allow duplicate declaration
if(true) {let AA; Let AA; //uncaught syntaxerror:identifier ' AA ' has already been declared}if(true) { var_aa; Let _aa; //uncaught syntaxerror:identifier ' _aa ' has already been declared}if(true) {let aa_; varAa_;//uncaught syntaxerror:identifier ' Aa_ ' has already been declared}
Let does not allow the same variable to be declared repeatedly within the same scope.
4. Global Variables vs Global Object Properties
The properties of global objects in ES5 are basically equivalent to global variables, but there are also differences, such as that global variables declared through VAR cannot be deleted from Window/global (Global is for the node environment), but are essentially equivalent to access to variables.
A strict distinction is made in ES6, where global variables declared with VAR and function are still used as properties of global objects, and the let
const
global variables declared by the command are not part of the global object's properties.
Let let_test = ' Test '; Console.log (window.let_test); // undefinedconsole.log (this. let_test); // undefined var var_test = ' Test '; Console.log (window.var_test); // TestConsole.log (this. var_test); // Test
Const
In addition to let, ES6 also introduces a const, which can also be used to create a block scope variable, but its value is fixed (constant). When using const to declare a variable, you must assign a value at the same time, or you will get an error. And any subsequent attempt to modify the value will cause an error.
const data; // uncaught syntaxerror:missing initializer in const declaration
if (true) { var a = 2; // Block Scope constants that are contained in the IF // Normal! // uncaught typeerror:assignment to constant variable. // 3// uncaught referenceerror:b is not defined
Note: A composite type const variable holds a reference. Because constants of a composite type do not point to data, but instead point to the address (stack) where the data (heap) is located, a composite type declared by Const can only guarantee that its address reference is unchanged, but its data is not guaranteed to be unchanged.
const arr= [1, 2]; // modify the data without modifying the reference address and execute the Arr.push (3) correctly; // [1, 2, 3] // Modify the value of the address saved by the ARR constant, error arr = []; // uncaught typeerror:assignment to constant variable.
The simple use of const cannot complete freezing of objects. You can use the Object.freeze () method to freeze an object. Objects returned using the Object.freeze () method will not be able to configure their properties (Definedproperty () is not available) and you cannot add new properties and remove existing properties. When you freeze an object completely, you need to freeze its object properties recursively.
Let obj = { 1, B: { 2 = 3//3function Freeze (obj) { object.freeze (obj); Object.values (obj). ForEach(function (value,index) { if(typeof value = = = ' object ') { freeze (value); } = 4//3
Summarize:
The advent of block-level scopes makes the widespread use of iife (immediately performing anonymous functions) unnecessary.
// anonymous function notation (function () { varfunction() {}; // ... window.$ =// block-scoped scope notation { function() {}; // ... window.$ = jQuery;}
Attached: Before ES6, the keyword with and keyword Try/catch will create related block-level scopes. The keyword with is deprecated, and we don't describe it much here. The ES3 specification specifies that the catch clause of Try/catch creates a block scope in which the declared variable is valid only within the catch.
Try { // perform an illegal operation to force an exception }catch (err) { // can execute normally! // uncaught referenceerror:err is not defined
Let and const----JavaScript series You don't know