ES6 let command and block scope and const command

ES6 let command and block scope and const command

First, the let command
1.ES6 added the let command to declare variables. Its usage is similar to var, but the declared variable is only valid within the code block where the let command is located.

{
  let a = 10;
  var b = 1;
}
console.log(b);//1
console.log(a);//Uncaught ReferenceError: a is not defined
The variable declared in the code above is only in the code where it is located block is valid.

 

2. The counter i is only valid in the body of the for loop. The part of the for loop that sets the loop variable is a parent scope, and the inside of the loop body is a separate child scope.
for (let i = 0; i < 10; i++) {
   //...
}
console.log(i);//Uncaught ReferenceError: i is not defined
In the above code, the counter i is only valid in the for loop body, in An error will be reported if the reference is outside the loop.
var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6]();//10
above In the code, the variable i is declared by the var command, and i is a global variable. Each time through the loop, the value of the variable i will change, and the i of the console.log(i) inside the function assigned to the array a in the loop points to the global i. Causes the runtime to output the value of i for the last round, which is 10.
var a = [];
for (let i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6]();//6
In the above code, the variable i is declared by let, and the current i is only valid in this cycle, so the i of each cycle is actually a new variable, so the final output is 6. The JavaScript engine will remember the value of the previous cycle, and when the variable i of the current cycle is initialized, it will be calculated on the basis of the previous cycle.
for (let i = 0; i < 3; i++) {
  let i = 'hello';
  console.log(i);
}
//hello
//hello
//hello
In the above code, hello is output 3 times. The variable i inside the function and the loop variable i are not in the same scope and have their own separate scopes. The for loop is special, the part that sets the loop variable is a parent scope, and the inside of the loop body is a separate child scope.

 

3. There is no variable promotion. The let command changes the grammatical behavior. The variables it declares must be used after the declaration, otherwise an error will be reported.
console.log(a);//undefined
var a = 1;
console.log(b);//Uncaught ReferenceError: b is not defined
let b = 1;
In the above code, the variable a is declared with the var command, and a variable will occur Elevate, when the script starts running, the variable a already exists, but has no value, so it will output undefined. The variable b is declared with the let command, and no variable hoisting occurs. Before declaring it, the variable b does not exist, then an error is thrown.

 

4. Temporary dead zone. Temporary dead zones and let and const statements do not have variable promotion, mainly to reduce runtime errors and prevent variables from being used before they are declared, resulting in unexpected behavior. As soon as the current scope is entered, the variable to be used already exists, but cannot be obtained. The variable can be obtained and used only after the variable is declared.
var a = 123;
if (true) {
  a = 'hello'; // ReferenceError
  let a;
}
In the above code, the global variable a already exists and can only be used after it is declared in the current scope.
typeof x; // ReferenceError
let x;
In the above code, a ReferenceError is thrown when typeof is run before the declaration.
typeof a;//undefined
As above, the variable a is not declared, typeof does not report an error, "temporary dead zone" means that typeof is no longer a 100% safe operation.
function a(x = y, y = 2) {
  return [x, y];
}
a();//Uncaught ReferenceError: y is not defined
As above, the default value of parameter x is equal to another parameter y, and at this time y is still There is no declaration, it belongs to the "dead zone", and here is the implicit declaration that is prone to error.
function a(x = 2, y = x) {
  return [x, y];
}
a();//[2, 2]
As implicitly declared above, the default value of y is x, and no error will be reported. At this time, x has been declared.

 

5. Repeated declarations are not allowed, repeated declarations in the same scope are not allowed, and parameters cannot be redeclared inside functions.
function func() {
  let a = 10;
  let a = 1;
}
// ReferenceError is reported
function func() {
  let a = 10;
  var a = 1;
}
// ReferenceError
is not allowed in the same scope, repeated declarations are the same as a variable.
function func(arg) {
  let arg; // ReferenceError reports
}
function func(arg) {
  {
    let arg; // undefined does not report errors
  }
}
Parameters cannot be redeclared inside a function.

 

2. Block-level scope
1. Block-level scope, ES5 only has global scope and function scope, but no block-level scope, which brings many unreasonable scenarios. Block-level scope allows arbitrary nesting, the outer scope cannot read the variables of the inner scope, the inner scope can define variables of the same name in the outer scope, and the block-level scope writing method can replace the immediately executed function expression ( IIFE).

var tmp = new Date();
function f() {
  console.log(tmp);
  if (true) {
    var tmp = 'hello world';
  }
}
f();// undefined
in the above code, the if code block The outer uses the outer tmp variable, and the inner uses the inner tmp variable. However, after the function f is executed, the output result is undefined, because the variable promotion causes the inner tmp variable to overwrite the outer tmp variable.
var s = 'hello';
for (var i = 0; i < s.length; i++) {
  console.log(s[i]);
}
console.log(i);
In the above code, the variable i is only used for Control the loop, but after the loop ends, it does not disappear and leaks into a global variable.
function f() {
  let n = 5;
  if (true) {
    let n = 10;
  }
  console.log(n); // 5
}
f();// 5
In the above code, the outer code block is not affected by the inner code block.
{{{{{let a = 'Hello World'}}}}};
{{{{
  {let a = 'Hello World'}
  console.log(a); // Error report
}}}};
In the above code, Block-level scope allows arbitrary nesting, and the outer scope cannot read the variables of the inner scope.
{{{{
  let a = 'Hello World';
  {let a = 'Hello World'}
}}}};
In the above code, the inner scope can define variables of the same name in the outer scope.
// IIFE writing method
(function () {
  var a = ...;
}());
// block-level scope writing method
{
  let a = ...;
}
In the above code, the appearance of block-level scope actually Makes the widely used Immediately Executed Function Expression (IIFE) unnecessary.

 

2. Block-level scope and functions. Functions cannot be referenced outside the block-level scope. You should avoid declaring functions in the block-level scope. If you really need it, you should also write it as a function expression instead of a function declaration statement. true in the case of curly brackets.
// Browser ES6 environment
function f() { console.log('I am outside!'); }
(function () {
  if (false) {
    // Repeat function f
    function f() { console.log ('I am inside!'); }
  }
  f();
}());
// Uncaught TypeError: f is not a function
ES6 stipulates that functions are allowed to be declared in block-level scope, and the behavior of the statement is similar to let, Not referenced outside of block scope.
The above code is in ES6 environment, the actual running code is as follows:
// ES6 environment of browser
function f() { console.log('I am outside!'); }
(function () {
  var f = undefined;
  if (false ) {
    function f() { console.log('I am inside!'); }
  }
  f();
}());
// Uncaught TypeError: f is not a function
As above, considering that the behavior caused by the environment is too different, you should avoid declaring functions in block-level scope.
// function declaration statement
{
  let a = 'secret';
  function f() {
    return a;
  }
}

// Function expression
{
  let a = 'secret';
  let f = function () {
    return a;
  };
}
As above, if really necessary, it should also be written as a function expression, not a function declaration.
// no error
'use strict';
if (true) {
  function f() {}
}
// error
'use strict';
if (true)function f() {}
As above, ES6 block scope allows to declare functions The rule is only true when curly brackets are used. If curly brackets are not used, an error will be reported.

 

Third, the const command: const declares a read-only constant. Once a variable is declared, it must be initialized immediately and cannot be left for later assignment. Only valid within the block-level scope where the declaration is made. There is a temporary dead zone and can only be used after the declared position. Not repeatable declarations. The value of the declared constant cannot be changed (numbers, strings, booleans), and it needs to be frozen for data of composite types (objects and arrays).
1. Must be initialized immediately.
    const a;// SyntaxError: Missing initializer in const declaration

2. The scope of const is the same as the let command: it is only valid in the block-level scope where the declaration is located.
    {
        const a = 1;
    }
    a // ReferenceError: a_d is not defined

3. The constant declared by the const command is also not promoted, and there is also a temporary dead zone, which can only be used after the declared position.
    {
        console.log(a);// ReferenceError: a is not defined
        const a = 1;
    }

4. The constant declared by const cannot be repeatedly declared like let.
    {
        var a = 1;
        let b = 'hello';
        const a = 2; // SyntaxError: Identifier 'a' has already been declared
        const b = 'world'; // SyntaxError: Identifier 'b' has already been declared
    }

5. The value of the constant cannot be changed, and you must be very careful when declaring a composite type data (object, array) as a constant, you need to freeze the object and use Object .freeze method, .
    const a = 1;
    a = 2;// TypeError: Assignment to constant variable.
For simple types of data (numbers, strings, booleans), the value is stored at the memory address pointed to by the variable, so it is equivalent to a constant. But for composite type data (mainly objects and arrays), the memory address pointed to by the variable is only a pointer, and const can only guarantee that the pointer is fixed. As for whether the data structure it points to is variable, it is completely out of control.
{
    const a = ['hello'];
    a.push('world');
    console.log(a); // ["hello", "world"]
    a = ['js']; // TypeError: Assignment to constant variable.
}
As above, the array a itself is writable, but if you assign another array to a, an error will be reported.

{
    const a = Object.freeze(['hello']);
    a.push('world');// TypeError: Cannot add property 1, object is not extensible
}
As above, if you want to freeze the object, you should use the Object.freeze method.

{
    const a = ['hello'];
    let func = (obj) => {
          Object.freeze(obj);
          Object.keys(obj).forEach( (key, i) => {
            if ( typeof obj[key] === 'object' ) {
                  func( obj[key] );
            }
          });
    };
    func(a);
    Object.isFrozen(a); // true
}
As above, in addition to freezing the object itself, the properties of the object are also Should be frozen, use the Object.isFrozen method to check if it is frozen and return true.

 

ES6 has changed a lot and is more logical. At present, there is no JavaScript proxy that fully supports ES6 (whether it is a browser environment or a server environment). Developers who are keen to use the latest features of the language need to translate ES6 code to ES5 code. Despite ES6's extensive updates, it is still fully backward compatible with previous versions, and the standardization committee decided to avoid "broken web experience" caused by incompatible versions of languages. The result is that all the old code works and the transition is smoother, but with that comes the problem of years old problems.
Babel conversion tool: https://babeljs.cn/
Compatibility: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/New_in_JavaScript/ECMAScript_6_support_in_Mozilla

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325006475&siteId=291194637