Detailed WeChat applet VAR, Let, Const usage and difference

WeChat applets can use JavaScript’s latest ES6 standard to develop, the WeChat applet, the WeChat appler can be considered as the JavaScript ES6 standard var, let, const usage and difference

Let Command

Basic Usage

ES6 adds the let command to declare the variable. Its usage is similar to VAR, but the declated variable is valid only within the code block where the Let command is located.

{Let a = 10; var b = 1;} a // referenceerror: a is not defined.b // 1
   
The above code is in the code block, and two variables are declared with Let and Var, respectively. Then call these two variables outside of the code block, and the resulting variables of the LET report error, the variable of the VAR declaration returns the correct value. This shows that the variables of the Let statement are only valid in the code block it. For the FOR cycle counter, it is appropriate to use the let command.

for (Let i = 0; i

In the above code, the counter i is active in the FOR cycle. In the cyclic body, it will be reported.
  If using var, the last output is 10. < 10; i++) {
 // ...
}
console.log(i);
// ReferenceError: i is not defined 

VAR A = []; for (VAR I = 0; i

In the above code, the variable i is a VAR command declaration, which is valid within the global scope, so there is only one variable I. Each time The value of the loop, the value of the variable I changes, and the cycle is assigned to console.log (i) inside the array A, and the I point to the global i. That is,There is a member of the member of the array a, which is the same i, which causes the last round of I to output the value of the last round of I, that is, 10.

If you use the LET, the declared variable is only valid in the block level scope, and the last output is 6.
  VAR A = []; for (let i = 0; i < 10; i++) {
 a[i] = function () {
  console.log(i);
 };
}
a[6](); // 10 
In the above code, the variable I It is a Let statement, the current i is only valid in this wheel cycle, so each loop I is actually a new variable, so the last output is 6. You may ask if each round of loop variable I It is re-declared, then how do it know the value of the last round of cycles, thus calculate the value of this round cycle? This is because the JavaScript engine remembers the value of the last round of loop, when the variable i of the wheel is initialized, On the basis of the last round of cycles.

In addition, there is also a special in the FOR cycle, that is, the part of the set cycle variable is a parent, and the interior of the circulation is a separate child. Scope.

for (Let i = 0; i
  < 10; i++) {
 a[i] = function () {
  console.log(i);
 };
}
a[6](); // 6 The above code is properly run, 3 times ABC. This indicates that the variable I and the circular variable I within the function are not in the same scope, with a separate scope. 

VAR command “Variable improvement” will occur, that is, the variable can be used before the declaration, the value is undefined. This phenomenon is less strange, according to the general logic, the variable should be used after a statement statement.

In order to correct this phenomenon, the let command changed the grammatical behavior. It declared the variables that must be used after the declaration, otherwise an error is reported.
 // VAR Console.log (foo); // Output undefinedvar foo = 2;// LET situation console.log (bar); // error ReferenceErrorlet bar = 2;  < 3; i++) {
 let i = 'abc';
 console.log(i);
}
// abc
// abc
// abc In the above code, the variable foo uses a VAR command declaration, and the variable increase That is, the script starts running, the variable foo already exists, but there is no value, so it will output. The variable bar is declared with the let command and does not increase the variable. This means that the variable bar does not exist before declaring it. If it is used, it will throw an error. 

As long as there is a set command in the block level, the variables it declares is “binding” (binding) area, no longer External impact.

VAR TMP = 123; if (true) {TMP = ‘abc’; // ReferenceError Let TMP;}

In the above code, there is a global variable TMP, but the block-level scope is declared a local variable TMP, causing the latter to bind this block-level scope, so before the LET declaration variable, the TMP assignment will be reported. ES6 clearly provides that if there is a Let and const command in the block, this block is declared by these commands, which forms a closed scope from the beginning. If you use these variables before the statement, you will report an error.
 In summary, the variable is not available before the line block is used to declare the variable. This is called "Temporate Dead Zone" in grammar, referred to as TDZ.   
IF (TRUE) {// TDZ Start TMP = ‘Abc’; // ReferenceError Console.log (TMP); // ReferenceError Let TMP; // TDZ end console.log (TMP); // undefined TMP = 123; console.log (tmp); // 123}

above code In the LET command declared the variable TMP, it belongs to the “dead zone” of the variable TMP. “Temporary Dead Area” also means that TypeOf is no longer a hundred percent safe operation.

TYPEOF X; // ReferenceErrorlet X;

In the above code, the variable x uses the LET command statement, so Before the declaration, it belongs to the “dead zone”, as long as this variable will be reported. Therefore, the TypeOf will throw a ReferenceError when running. As a comparison, if a variable is not declared, use TypeOf but will not report an error.
   TYPEOF undeclared_variable // "undefined" 
In the above code, undeclared_variable is a variable name that does not exist. The result returns “undefined”. So, the TypeOf operator is 100% security before no letters, never report error. This is not established now. Such a design is to make everyone develop a good program habit, and the variable must be used after the statement, otherwise it will report an error.

Some “dead zones” is more concealed, and it is not easy to discover.

Function Bar (x = y, y = 2) {RETURN [x, y];} bar (); // report error

  In the above code, the BAR function is called (some implementation may not be reported) because the parameter x default value is equal to another parameter y, and at this time, Y has not yet declared, belonging to "dead zone". If the default value of Y is X, it will not report error, because X has declared.  
Function Bar (x = 2, y = x) {RETURN [x, y];} bar (); // [2, 2]

In addition, the following code will also report an error, different from the behavior of VAR.

// Does not report the error VAR x = x; // error LET X = x; // ReferenceError: x is not defined
   
The above code is reported, and it is also because of the temporary dead zone. When using the Let statement variable, the variable will be reported if the variable is not used before the declaration is not done. The above line belongs to this situation, and the value of X is taken before the declaration statement is not executed, resulting in an error “X undefined”. ES6 specifies that the temporary dead zone and let, the const statement does not increase the increase in variables, mainly to reduce runtime errors, preventing this variable before variable declaration, resulting in unexpected behavior. Such errors are very common in ES5, and now there is such regulations to avoid such errors.

In summary, the essence of the temporary dead zone is that as long as it enters the current scope, the variables to be used have already existed, but it is not available. Only when the code, the line of code that is declared, can be obtained and Use this variable.

No repeated declaration
 The LET is not allowed to repeat the same variable in the same scope.   
// error FUNCTION () {let a = 10; varA = 1;} // error FUNCTION () {let a = 10; Let a = 1;}
Therefore, the parameters cannot be re-declared in the function inside the function.

Function func (arg) {let arg; // error} function func (arg) {{let arg; // does not report an error}}

  Block-level scope  
Why do you need block level scope?

ES5 only has a global scope and function scope, there is no block-level scope, which brings a lot of unreasonable scenes.

The first kind of scene may cover the outer variable.
 VAR TMP = New Date (); function f () {console.log (tmp); if (false) {var TMP = 'Hello World';}} f (); // undefined   The original intend to the above code is that the outer layer of the TMP variable is used in the outside of the IF code block, and the inner layer TMP variable is used. However, after the function f is executed, the output is undefined because the variable is increased, causing the inner layer TMP variable to cover the outer layer TMP variable. 
The second scenario is used to count the cyclic variables to leak the global variable.

VAR S = ‘Hello’; for (VAR I = 0; I
  Among the above code, the variable i is only used to control the cycle, but after the end of the cycle, it did not disappear and leaked into global variables. 
The block-level scope of ES6

The LET actually adds a block-level scope for JavaScript.

Function F1 () {let n = 5; if (true) {let n = 10;} console.log (n); // 5}

The above function has two code blocks, which declares that the variable N is run, and outputs 5 after running. This means that the outer class block is not affected by the inner layer code block. If both VAR definition variables n twice, the value of the last output is 10. The ES6 allows any nested in the block-level scope.

{{{{Let INSANE = ‘Hello World’}}}}};
   above A five-layer block-level scope is used. The outer scope cannot read the variables of the inner layer. 
{{{{let insane = ‘hello world’} console.log (insane); // error}}}};

The inner layer scope can define the same name variable in the outer layer.
   {{{letry {{{let insane = 'Hello World'; {let insane = 'hello world'}}}}}; 

The emergence of block-level scope, in fact, the immediate execution function expression (IIFE) that has been widely applied is no longer necessary.

// IIFE Writing (Function() {var TMP = …; …} ()); // block level scope write method {let TMP = …; …}

Blood-level scope and function declaration
Can function not declared in block-level scope? This is a fairly confusing problem.
  ES5 specifies that the function can only be declared in the top-level scope and function scope, and cannot be declared at block level scope.  
// A case}} {function f () {}} // case}} Catch (e) {/ / …}

The above two functions are declared, which are illegal according to the provisions of the ES5.

However, the browser does not comply with this provision. In order to comply with the previous old code, it is supported in the block level scope, so the above two cases can actually run, will not report error.

ES6 introduces a block-level scope and explicitly allows a function in block-level scope. ES6 specifies that among the block-level scope, the behavior of the function declaration statement is similar to the LET, which is not referenced outside the block level scope.
 Function f () {Console.log ('I am outside!');} (Function () {if (false) {// Repeat Declaration One function f Function f () {console.log ('I am inside!');}} f ();} ());  < s.length; i++) {
 console.log(s[i]);
}
console.log(i); // 5 The above code is run in ES5, Will get "I am Inside!", Because the function f in IF will be upgraded to function headThe actual code of operation is as follows. 
// ES5 Environment Function F () {Console.log (‘I am Outside!’);} (Function () {function f () {Console.log (‘I am inside!’);} F (false) {} f ();} ());

ES6 is completely different, theoretical Get “I am outside!”. Because the function within the block-level scope is similar to the LET, there is no impact outside the scope. However, if you really run the above code in the ES6 browser, it will report an error. Why is this?

It turns out that if the rules of the function in the block-level scope declaration are changed, it is clear that the old code will have a big impact on the old code. To alleviate the incompatible problem, ES6 is in the appendix B. The browser’s implementation can not comply with the above provisions and have its own behavior.

Allows the declaration function

function declaration within the block level scope, that is, the header of the global scope or function scope. At the same time, the function declaration will also increase the head of the block-level scope of the position.
  Note that the above three rules are only valid for the ES6 browser, and the implementation of other environments does not have to comply, or the function declaration of the block-level scope is treated as a LET.  
According to these three rules, in the ES6 environment of the browser, the function in the block-level scope declaration is similar to the variable of the Var declaration.

// Browser ES6 Environment Function F () {Console.log (‘I am Outside!’);} (Function () {if (false) { / / Declaration of a function fFunction f () {console.log (‘I am inSide!’);}} f ();} ()); // uncaught typeerror: f is not a function

The above code will report an error in the ES6 browser, because the actual run is the following code.
   // Browser ES6 Environment Function F () {Console.log ('I am Outside!');} () {Var f = undefined; IF (False) {Function F () {Console.log ('I am inSide!');}} f ();} ()); // uncaught typeerror: f is not a function 

The difference in behavior caused by the environment is too large, and should be avoided in the block level scope. If you do need, you should also write a function expression, not a function declaration statement.
 // Function declaration statement {let a = 'secret'; function f () {return a;}} // Function expression {let a = 'secret' {RETURN A;};}   
There is also a place that needs attention. The block-level scope of the ES6 allows the rules of the declaration function, only in the case of braces, if no braces are used, it will be reported.

// Does not report the wrong ‘Use STRICT ‘; if (true) {function f () {}} // error’ use strict ‘; if (true) function f () {}
   
DO expression

Essentially, block-level scope is a statement, encapsulates multiple operations together without returning values.
 {Let T = f (); t = t * t + 1;}   
above The block level scope packages two statements together. However, in the block-level scope, there is no way to obtain the value of T because the block-level scope does not return the value unless T is global variable.

There is now a proposal to make the block-level scope can become an expression, that is, the method can return the value, the method is to add DO before the block level scope, so that it becomes a DO expression.

Let x = do {let t = f (); t * t + 1;};

In the above code, the variable x obtains the return value of the entire block-level scope.
  const command  
Basic usage
constly declares a read-only constant. Once declare, the value of constant cannot be changed.

Const pi = 3.1415; PI // 3.1415Pi = 3; // TypeError: Assignment to constant variable.

The above code indicates that the value of changing constants will report an error.
  constant variables must not change the value, this means that once, CONSTDeclating variables, you must initialize immediately and cannot be assigned.  
Const foo; // syntaxerror: Missing Initializer in const decration The above code indicates that for Const, only declares that not assignment, it will report an error. The role of Const is the same as the let command: valid only within the block-level scope where the declaration is located. } Max // Uncaught ReferenceError: max is not defined

The constant of const command declaration is not improved, and there is also a temporary death. The area can only be used later in the statement.
 IF (true) {console.log (max); // ReferenceError const Max = 5;}   
The above code is called before the constant max declaration, and the result is an error.

Constant statements are also unable to declare as LET.

VAR Message = “Hello!”; Let Age = 25; // The following two lines will report the error const message = “Goodbye!”; Const Age = 30;

constantly guaranteed, not the value of variables must not be changed, but the memory address pointing to the variable must not be changed . For simple types of data (values, strings, boolean values), the value saves the memory address pointed to by the variable, which is equivalent to constant. But for composite types of data (mainly objects and arrays), changeThe amount points to the memory address, saved is just a pointer, and const can only guarantee that this pointer is fixed, as for the data structure it points to, it cannot be controlled at all. Therefore, declare an object as a constant must be very careful.

const foo = {}; // Add an attribute to FOO, can successfully foo.prop = 123; foo.prop // 123 // Point Foo to another Objects will be reported to foo = {}; // typeerror: “foo” is read-only
  In the above code, the constant foo stores an address, this address Point to an object. The non-variable is just this address, that is, the FOO cannot point to another address, but the object itself is variable, so it is still possible to add new attributes to it.  
The following is another example.

const a = []; a.push (‘hello’); // can execute a.length = 0; // can be executed A = [‘Dave’ ]; // error

In the above code, constant A is an array, which is writable, but if another array is assigned to A, it will Error.
 If you really want to freeze the object, you should use the Object.Freeze method.   
Const foo = Object.freeze ({}); // When the routine mode, the following line does not work; // Strict mode, the line will report an error Foo. PROP = 123;

In the above code, the constant FOO points to a frozen object, so adding a new attribute does not work, and it will report an error in strict mode.

In addition to freezing the object itself,The properties of the object should also be frozen. Below is a function that completely freezes the object.
  VAR constantize = (obj) => {Object.Freeze (obj); object.keys (obj) .foreach ((KEY, I) => {IF TypeOf obj [key] === 'Object') {constantize (obj [key]);}});};  
6 methods of ES6 declared variables
ES5 has only two ways of declared variables: var command and function command. In addition to adding the let and const commands, the following sections will also mention that the other two declared variables: import commands and class commands. Therefore, ES6 has a total of six ways to declare variables.

The attribute of the top-level object
 The top-level object, in the browser environment, the Window object, in Node refers to the Global object. In ES5, the attributes of the top-level object are equivalent to global variables.   
WINDOW.A = 1; A / / 1A = 2; WINDOW.A / / 2

In the code, the attribute assignment of the top-level object is assigned to the global variable, is the same thing.

The attribute of the top-level object is linked to the global variable, which is considered to be one of the largest design and loss of JavaScript language. Such a design has brought a few big problems. The first thing is not possible to report the variables that have not declared in the compile, only the runtime can know (because the global variable may be the attribute of the top object, and the attribute Creative is dynamic); second, the programmer is easy to create a global variable (such as typing error); Finally, the attribute of the top-level object is to read and write everywhere, this is notIt is often not conducive to modular programming. On the other hand, the Window object has entity meanings, refers to the window object of the browser. The top-level object is an object that has an entity and is not suitable.

ES6 In order to change this, on the one hand, in order to maintain the compatibility, the variety of the var command and the Function command declared, still is the attribute of the top-level object; on the other hand, the list command, const command, CLASS The overall variable of the command statement is not the attribute of the top object. That is, starting from ES6, the global variable will gradually be gradually detached with the attributes of the top object.

VAR A = 1; // If in the Node’s REPL environment, it can be written as global.a // or use a general method, write to this.awindow.a // 1ub B = 1; WINDOW.B // Undefined
  In the above code, the global variable A is declared by a VAR command, so it is the attribute of the top object; the global variable B is Command declaration, so it is not the properties of the top-level object, returning undefined.  
Global Object
The top-level object of ES5 is itself a problem because it is not uniform in various implementations.

Inside the browser, the top object is Window, but Node and Web Worker have no Window.

Inside the browser and the Web Worker, Self also points to the top object, but Node doesn’t have Self.
Node, the top object is Global, but other environments are not supported. In order to be able to take the top object in the same paragraph, it is now generally using the THIS variable, but there are limitations.
 In the global environment, this will return to the top object. However, in the Node module and the ES6 module, this returns the current module.   Inside the function, if the function is not run as an object, but is simply functions as a function, this will point to the top object. However, in strict mode, this sometimes returns undefined. 
Whether it is strict mode, or normal mode, New function (‘return this’) () always returns a global object. However, if the browser uses the CSP (Content Security Policy, the Content Security Policy), the EVAL, New Function These methods may not be available.

In summary, it is difficult to find a method, which can be taken to the top object in all cases. Here are two ways to use.

// Method 1 (Typeof WinDow! == ‘undefined’? Window: (TypeOf Process === ‘Object’ && TypeOf Require === ‘Function “&& TYPEOF GLOBAL === ‘Object’)? Global: this); // Method Two Var getGlobal = Function () {i (TypeOf Self! == ‘undefined’) {Return Self;} IF (TypeOf WINDOW! === Undefined ‘) {Return window;} if (TypeOf Global! ==’ undefined ‘) {Return Global;} throw new error (‘ unable to locate global object “;};

There is now a proposal that introduces Global as the top of the language standard.Layer object. That is to say, in all environments, Global is existing, which can get the top object from it. The gasket library system.global simulates this proposal and can get Global in all the environment.

// CommonJS Write Require (‘System.global/shim’) (); // ES6 Module Writing Import Shim from ‘System.global/shim’; Shim ();
  The above code ensures that the Global object exists in various environments.  
// Commonjs Writing var Global = Require (‘system.global’) (); // ES6 module Writing Import getGlobal from ‘system.global’; const Global = getGlobal ();

The above code puts the top object in the variable Global.

More about WeChat Approach Development and JavaScript ES6 Standard Specification, please check the following related articles

© Copyright Notice
THE END
Just support it if you like
like0
share
comment Grab the couch

Please log in to comment