A, the premise

Solve the unreasonable scenario that ES5 has only global scope and function scope, but no block-level scope.Copy the code

let


Basic usage

The usage is the same as var, except that the variables declared by let are valid only in the code block in which the let command resides

{
  let a = 10;
  var b = 1;
}

a // ReferenceError: a is not defined.
b // 1
Copy the code

Var can be called outside the code block, while let can be called outside the code block. So the let declaration can only be called in the current code block it declares.


Variable ascension

When var is used, “variable promotion” occurs, that is, the variable can be used before the declaration, the value of undefined. Let changes this, but must be declared before use, and an error is reported if used before declaration. As follows:

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

As long as a let or const command exists inside a block-level scope, its declared variables are “bound” within the scope, unaffected by external influences. The nature of a temporary dead zone is that as soon as you enter the current scope, the variable you want to use already exists, but it cannot be retrieved until the line of code that declared the variable appears. As follows:

var tmp = 123;

if (true) {
  tmp = 'abc'; // ReferenceError
  let tmp;
}
Copy the code

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.

In short, the variable is not available within the code block until it is declared using the let command. This is grammatically known as a “temporal dead zone” (TDZ). As follows:

if (true) {// TDZ start TMP ='abc'; // ReferenceError
  console.log(tmp); // ReferenceError

  lettmp; // TDZ end console.log(TMP); // undefined tmp = 123; console.log(tmp); / / 123}Copy the code
Note:

When a variable is declared using let, an error is reported whenever the variable is used before the declaration is complete. The above line is an example of this situation, where the value of x is fetched before the declaration of variable x is completed, causing an error “x undefined”. ++

Duplicate declarations are not allowed

Let does not allow the same variable to be declared in the same scope, as follows:

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

Or as follows:

function func(arg) {
  letarg; } func() // errorfunction func(arg) {
  {
    letarg; }} func(Copy the code
Block-level scope

As mentioned above, there is no block-level scope in ES5, only functional scope and global scope, which brings up some problems as follows:

var tmp = new Date();

function f() {
  console.log(tmp);
  if (false) {
    var tmp = 'hello world'; } } f(); // undefined defines the outer declaration to be overwritten by the inner declaration, which uses the outer declaration. The inner variable is raised to cause undefindedCopy the code
Count loop global leak as follows:
var s = 'hello';

for(var i = 0; i < s.length; i++) { console.log(s[i]); } console.log(i); // 1, 2, 3, 4, 5Copy the code
ES6’s block-level scope, actually added by let, is as follows:
function f1() {
  let n = 5;
  if (true) {
    letn = 10; } console.log(n); // 5} The inner and outer layers of n do not interfere with each otherCopy the code
ES6 allows arbitrary nesting of scopes without interfering with each other, as follows:
The inner and outer layers can be named {{{{let insane = 'Hello World';
  {let insane = 'Hello World'}}}}}; Or {{{{{let insane = 'Hello World'} console.log(insane); / / error}}}};Copy the code

Block-level scopes make it unnecessary to write the following instant-execution functions:

// IIFE ()function() { var tmp = ... ; . } ()); // block level scope {lettmp = ... ; . }Copy the code
Block-level scope and function declarations

In ES5, functions can only be on the top floor scope and scope statement, not the block-level scope statement, but the browser for compatibility, or can be declared in the block-level scope, theoretically in the ES6 block-level scope statement function, in the external calls complains, considering the environment problem, should be avoided in the block-level scope statement function, If necessary, it should also be written as a function expression rather than a function declaration statement, as follows:

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

const

Const declares a constant as follows:

Const PI = 3.1415; PI = 3; // TypeError: Assignment to constant variable.Copy the code

If you’re assigning after the declaration, it’s going to get an error, and because you’re declaring a constant, it’s going to get an error if you’re not assigning after the declaration

Const, like let, is declared only at the current block-level scope. There is also no promotion declaration and a temporary dead zone that can only be used after a declaration and, like let, cannot be re-declared or reassigned.

Important:

A const cannot change the value, not the value, but the value held at the memory address to which the variable points. For simple types (values, strings, booleans), the value is held at the memory address to which the variable points and is therefore equivalent to a constant. In the case of composite types, the variable points to a memory address that holds only a pointer to the actual data. Const guarantees that the pointer is fixed. The data structure it points to is not controllable, as follows:

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 The constant foo stores an address that refers 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.Copy the code

or

const a = [];
a.push('Hello'); // 可执行
a.length = 0;    // 可执行
a = ['Dave']; The constant A is an array. The array itself is writable, but an error is reported if another array is assigned to aCopy the code
If you really want to freeze the declared object, you should use it if you cannot change it againobject.freeze()
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; The Object can also freeze var constantize = (obj) => {object.freeze (obj); Object.keys(obj).forEach( (key, i) => {if ( typeof obj[key] === 'object') { constantize( obj[key] ); }}); };Copy the code

ES6 six ways to declare variables

1. function
2. var
3. let
4. const
5. import 
6. class
Copy the code

Properties of the top-level object

In ES5, the properties of the top-level object are equivalent to global variables.

window.a = 1;
a // 1

a = 2;
window.a // 2
Copy the code

Global object

The top-level object of ES5 is itself a problem because it is not uniform across implementations.

  1. In browsers, the top-level object is window, but Nodes and Web workers don’t have Windows.
  2. In browsers and Web workers, self also points to the top-level object, but Node has no self.
  3. In Node, the top-level object is global, which is not supported in any other environment.

In order for the same code to be able to fetch the top-level object in any environment, it is now common to use this variable, but there are limitations.

  1. In a global context, this returns the top-level object. However, in the Node module and ES6 module, this returns the current module.
  2. This inside of a function, if the function is not run as a method on an object, but is simply run as a function, this points to the top-level object. However, in strict mode, this will return undefined.
  3. In strict or normal mode, new Function(‘return this’)() always returns a global object. However, if the browser uses CSP (Content Security Policy), eval and new Function may not work.

Welcome to the public account [front-end development xiaobai]