preface

I this is the first time to write an article, record the usual in the study of some harvest and speech, these notes if there are mistakes in the place estrous inform correction, very grateful, I am not literary, light spray, thank you.

1. Let the order

scope

ES6 added the let command to declare variables. Its use is similar to var, but the declared variable is only valid within the code block in which the let command resides. Here’s an example:

for (let i = 0; i < 10; i++) {
  // ...
}

console.log(i);
// undefind
Copy the code

The variable I declared by let can only be accessed inside the for loop, not outside the for loop, so the output is undefind. If you replace let with var, the output is 10

Another special feature of the for loop is that the part that sets the variables of the loop is a parent scope, while the inside of the loop body is a separate child scope. It can be understood by the following example:

for (let i = 0; i < 3; i++) {
  let i = 'abc';
  console.log(i);
}
// abc
// abc
// abc
Copy the code

The above code works correctly, printing three ABCs. This indicates that the variable I inside the function and the loop variable I are not in the same scope and have separate scopes.

There is no variable promotion

The var command will cause “variable promotion”, that is, the variable can be used before the declaration, the value of undefined. This is not the case with the let command.

// var case console.log(foo); Var foo = 2; //letThe situation of the console. The log (bar); / / error ReferenceErrorlet bar = 2;
Copy the code

In the above code, the variable foo is declared with the var command, and the variable promotion occurs. That is, when the script starts running, the variable foo already exists, but has no value, so undefined is printed. The variable bar is declared with the let command, and no variable promotion occurs. This means that the variable bar does not exist until it is declared, and an error will be thrown if it is used.

The above example gives an error because it creates a temporary dead zone

Temporary dead zone

ES6 explicitly states that if there are let and const commands in a block, the variables declared by the block to those commands form a closed scope from the start. Any time these variables are used before declaration, an error is reported.

typeof x; // ReferenceError
let x;
Copy the code

When using Typeof, an error occurs

ES6 makes it clear that temporary dead zones and let and const statements do not promote variables. The main purpose of ES6 is to reduce runtime errors and prevent the variable from being used before it is declared, resulting in unexpected behavior. Such errors are common in ES5, and with this provision, it’s easy to avoid them.

In short, the essence of a temporary dead zone is that the variable you want to use already exists as soon as you enter the current scope, but you can’t get it until the line of code that declared the variable appears.

Duplicate declarations are not allowed

Let does not allow the same variable to be declared twice in the same scope.

/ / an errorfunction func() {
  let a = 10;
  var a = 1;
}
Copy the code

2. Block level scope

ES5 has only global and functional scopes, not block-level scopes, which leads to a lot of irrational scenarios. In the first scenario, the inner variables may override the outer variables.

var tmp = new Date();

function f() {
  console.log(tmp);
  if (false) {
    var tmp = 'hello world';
  }
}

f();  // undefind
Copy the code

Var TMP = TMP; var TMP = TMP; var TMP = TMP; This code, so the final result is undefined. If you change the above code to look like this:

var tmp = new Date();

function f() {
  console.log(tmp);
  if (false) {
    let tmp = 'hello world'; } } f(); // Outputs the current timeCopy the code

Block-level scopes and function declarations

ES6 states that a function declaration statement in a block-level scope behaves like a LET and cannot be referenced outside the block-level scope.

function f() { console.log('I am outside! '); }

(function () {
  if (false) {// declare the function f againfunction f() { console.log('I am inside! '); } } f(); } ());Copy the code

The above code will run differently in ES5 and ES6 browsers. Running on ES5 will result in “I am inside!” Because f declared inside if is promoted to the function header, the actual code to run is as follows.

/ / ES5 environmentfunction f() { console.log('I am outside! '); }

(function () {
  function f() { console.log('I am inside! '); }
  if (false) { } f(); } ());Copy the code

The ES6 is completely different, theoretically getting “I am outside!” . Because functions declared inside the block-level scope are like lets, they have no effect outside the scope. However, if you actually run the above code in an ES6 browser, you will get an error. Why?

It turns out that if you change the processing rules for functions declared in block-level scopes, you can obviously have a big impact on older code. To mitigate the resulting incompatibilities, ES6 provides in Appendix B that browser implementations can behave in their own way.

  • Allows functions to be declared in block-level scopes.
  • Function declarations are similar to var in that they are promoted to the global scope or to the head of the function scope.
  • Function declarations are also promoted to the head of their block-level scope.

Note that the above three rules apply only to browser implementations of ES6. Implementations of other environments do not follow these rules, and block-scoped function declarations are treated as lets. According to these three rules, in the browser’s ES6 environment, block-level scoped functions behave like variables declared by var.

// ES6 environment of the browserfunction f() { console.log('I am outside! '); }

(function () {
  if (false) {// declare the function f againfunction f() { console.log('I am inside! '); } } f(); } ()); // Uncaught TypeError: f is not afunction
Copy the code

The above code will generate an error in any ES6-compliant browser because it is actually running the following code.

// ES6 environment of the browserfunction 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 afunction
Copy the code

You should avoid declaring functions in block-level scopes because of the wide variation in behavior caused by the environment. If necessary, write it as a function expression rather than a function declaration statement.

// function declaration statement {let a = 'secret';
  function f() {
    returna; }} // function expression {let a = 'secret';
  let f = function () {
    return a;
  };
}
Copy the code

Const command

  • constDeclare a read-only constant. Once declared, the value of a constant cannot be changed.
  • constThe scope of the let command is the same as that of the let command: it is valid only in the block-level scope in which the declaration is made.
  • constDeclared variables must not change their value
  • constConstants declared by the command also do not promote and also have temporary dead zones that can only be used after the declared position

nature

What const actually guarantees is not that the value of the variable cannot be changed, but that the data stored at the memory address to which the variable points cannot be changed. For data of simple types (values, strings, booleans), the value is stored at the memory address to which the variable points, and is therefore equivalent to a constant. But for complex type data (mainly objects and arrays), variable pointing to the memory address, save only a pointer to the actual data, const can guarantee the pointer is fixed (i.e., always points to the other a fixed address), as far as it is pointing to the data structure of variable, is completely unable to control. Therefore, declaring an object as a constant must be done with great care.

const foo = {}; // Add an attribute to foo, which succeeds foo.prop = 123; Foo. Prop // 123 // Pointing foo to another object will result in an error foo = {}; // TypeError:"foo" is read-only
Copy the code

In the code above, the constant foo stores an address that points to an object. Only the address is immutable, that is, you can’t point foo to another address, but the object itself is mutable, so you can still add new attributes to it.

If you really want to freeze an Object, you should use the object. freeze method.

const foo = Object.freeze({}); // In normal mode, the following line does not work; // In strict mode, this line will report an error foo.prop = 123;Copy the code

In addition to freezing the object itself, properties of the object should also be frozen. Here is a function that freezes an object completely.

var constantize = (obj) => {
  Object.freeze(obj);
  Object.keys(obj).forEach( (key, i) => {
    if ( typeof obj[key] === 'object') { constantize( obj[key] ); }}); };Copy the code

conclusion

Most of this article is reference nguyen other great god ECMAScript 6 portal (http://es6.ruanyifeng.com/#docs/let) this article if you have not clear place please refer to other great god of ruan, this article just himself a notes. If you think this article is helpful to you, please give me a thumbs up and a little encouragement. I will update the article more in the future and record my growth process.