Javascript variables to enhance understanding

Foreword

2922 word article, read it takes about 8 minutes.

In conclusion: What is a variable lift, use var variable function classes let, const, function, class statement has no difference in the variable lift of the time.

Either vulgar or lonely.

text

Javascript variables in lifting can say is that it be used before variable declarations in the program:

console.log(a); // undefined
var a = 1;

It can be seen before we can declare a variable to call a normal, actual performance of code like this:

var a;
console.log(a); // undefined
a = 1;

But in fact, the code has not been changed, but we guess the above code, in fact Javascript engine did not move or change the code in the implementation of the results of these few lines of code. In the end what happened?

Variable lift

During the compiled code, the code that is actually executing one moment, the engine will block all variable declarations and function declarations are recorded. These functions and variable declarations statements are recorded in a file named lexical environment data structure. Lexical Environment is a Javascript engine in a recording function declarations and variable data structure, it will be stored directly in memory. Therefore, the above console.log(a)can be performed normally.

What is the lexical environment

The so-called lexical environment is a kind of identifier - variable structure mapping (where the identifier refers to the names of the variables / functions, a variable is a reference to the actual object or [an array containing the object function and a type of] basic data type).

Simply put, the lexical environment is the Javascript engine used to store local variables and object references.

Environment lexical structure represented by the following pseudo-code:

LexicalEnvironment = {
  Identifier:  <value>,
  Identifier:  <function object>
}

Learn more about the lexical environment before you can see the translation of bloggers: understanding the context of the implementation and execution stack of Javascript .

Learn lexical environment Let me look in turn use var, const, let, function, classsituation variable or function declaration.

enhance the function declaration

helloWorld();  // 打印 'Hello World!'
function helloWorld(){
  console.log('Hello World!');
}

We already know, will function declarations will be recorded in the lexical environment and stored in memory at compile time, so we can access the function before the actual statement in the function.

The above statement is stored in the lexical environment function like this:

lexicalEnvironment = {
  helloWorld: < func >
}

So executing code when Javascript engine encounter helloWorld()this line of code, will look at the lexical environment, and then locate the function and execute it.

Function expression

Note that only the function declaration will be directly enhance the function using a function expression declarations are not promoted, look at the code below:

helloWorld();  // TypeError: helloWorld is not a function
var helloWorld = function(){
  console.log('Hello World!');
}

As above, the error codes. Use varstatement helloWorld is a variable, not a function, Javascript engine would treat it as ordinary variables to deal with, but will not give it a value in the lexical environment.

Save lexical environment like this:

lexicalEnvironment = {
  helloWorld: undefined
}

The above code in order to function correctly can be rewritten as follows:

var helloWorld = function(){
  console.log('Hello World!');
}
helloWorld();  // 打印 'Hello World!'

var variable lift

See a use varexample of variable declaration:

console.log(a); // 打印 'undefined'
var a = 3;

If you press the top functionway to understand the function declaration, there should print 3, but actually printed undefined.

Remember: the so-called statement lift only at compile Javascript engine in a lexical environment, but does not give them the assignment function declarations and variable declarations storage. Wait until the execution phase, the real implementation of the assignment to the line when the lexical environment will be updated.

But why the above code printed undefinedit?

Javascript engine will be used in the compilation phase vardeclare variables stored in a lexical environment, and it is initialized undefined. To the implementation phase, such as execution time assigned to that line of code, the value will lexical environment variable is updated.

Therefore, the above lexical environment initialization code like this:

lexicalEnvironment = {
  a: undefined
}

This also explains why the function is performed using a function expression will be declared in the previous error, why the above code will print undefined. When the code is executed var a = 3;when this line, the value of a lexical environment is updated, then the lexical environment will be updated as follows:

lexicalEnvironment = {
  a: 3
}

let const variables and upgrade

See a use letexample of variable declaration:

console.log(a);
let a = 3;

Output:

Uncaught ReferenceError: Cannot access 'a' before initialization

Look at an example of using const variable declaration:

console.log(b);
const b = 1;

Output:

Uncaught ReferenceError: Cannot access 'b' before initialization

And vardifferent code into the same structure letor constdirectly the error.

Is the use letand constvariable declaration of variables to enhance the situation does not exist?

In fact, all the variables in Javascript declared ( var, const, let, function, class) there is the case of variable promotion. Use varvariables declared in the lexical environment will be initialized undefined, but by letand constvariable declarations will not be initialized.

Use letand constvariable declarations only when the assignment to execute the line of code that will really give him an assignment, this also means that in the implementation of access that variable before the line of code to the variable declaration will be an error, this is what we often say that the temporary dead zone (TDZ) . That can not be accessed variables before variable declarations.

When the execution to the line variable declarations, but still no assignment, then use the letdeclared variables will be initialized undefined; use constdeclared variables will error; see actual examples:

let a;
console.log(a); // 输出 undefined
a = 5;

In the code compilation phase, Javascript engine variable will be stored in a lexical environment, and a holding in the uninitialized state. At this point lexical environment like this:

lexicalEnvironment = {
  a: <uninitialized>
}

At this point if you try to access a variable or b, Javascript engine can be found in the lexical environment variable, but this time in an uninitialized variable state, and therefore throws a reference error.

Then in the implementation phase, Javascript engine to execute when the assignment (the professional point called lexical bindings) that line, will assess the value to be assigned, if not assigned, simply a statement at this time will give the letvariable declaration assigned undefined; lexical environment case like this:

lexicalEnvironment = {
  a: undefined
}

When performing the a = 5time this line, lexical environment again update:

lexicalEnvironment = {
  a: 5
}

Look at the use of constdeclaration code:

let a;
console.log(a);
a = 5;
const b;
console.log(b);

Output:

Uncaught SyntaxError: Missing initializer in const declaration

The above error code directly, nor the value of a print, direct error, in fact, is the code at compile time already being given, did not even perform to console.log(a);this line of code.

Note: In the function, as long as it can refer to the variable in the variable declaration after the error will not.

What does that mean? Look at the following code:

function foo () {
  console.log(a);
}
let a = 20;
foo(); // 打印 20

But in the following code will throw an error:

function foo () {
  console.log(a);
}
foo();
let a = 20; // 报错: Uncaught ReferenceError: Cannot access 'a' before initialization

The reason being given here requires a combination of execution context and Javascript execution stack in order to understand, because the global execution context saved in a lexical environment variable in an uninitialized state, call the function foo, created a function execution context and function foo execution of the execution context of a global variable a visit, but still in a non-initialized state (at this time let a = 20has not been performed). Therefore error.

Here need to correct a misunderstanding, that is let, and constdeclare variables only temporary dead zone, there is no variable lift, in fact, is wrong, for example demonstrate an understanding about:

let a = 1;
{
  console.log(a);
  let a = 2;
}

The code above will be given:

Uncaught ReferenceError: Cannot access 'a' before initialization

If there is no variable lift, in theory, does not complain fishes.

class declaration upgrade

And let, constsimilarly, the use of classdeclared class will also be improved, then this class declaration would be stored in the lexical environment but in an uninitialized state, until the implementation of the line of code to assign values to variables, will be initialized. In addition, classthere is a class declaration as a temporary dead zone (TDZ) . Look at an example:

let peter = new Person('Peter', 25); 
console.log(peter);
class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}

print:

Uncaught ReferenceError: Cannot access 'Person' before initialization

Can be rewritten as follows normal run:

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}
let peter = new Person('Peter', 25); 
console.log(peter);
// Person { name: 'Peter', age: 25 }

The above code at compile time, lexical environment like this:

lexicalEnvironment = {
  Person: <uninitialized>
}

It is then performed to classdeclare that the line of code, then the lexical environment like this:

lexicalEnvironment = {
  Person: <Person object>
}

NOTE: use a constructor function to instantiate an object does not complain:

let peter = new Person('Peter', 25);
console.log(peter);
function Person(name, age) {

    this.name = name;
    this.age = age;
}
// Person { name: 'Peter', age: 25 }

The above code to run properly.

Class expression

And functions as an expression, the expression is the same class will be promoted, such as:

let peter = new Person('Peter', 25);
console.log(peter);
let Person = class {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}

Error:

Uncaught ReferenceError: Cannot access 'Person' before initialization

To properly run, can be rewritten as follows:

let Person = class {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}
let peter = new Person('Peter', 25); 
console.log(peter);
// Person { name: 'Peter', age: 25 }

In other words, whether the rules and variable declarations function expression or class expressions follow the same.

in conclusion

Whether var, const, let, function, classvariable or function declarations are the presence of variable promotion. Help us to enhance proper understanding of the variables to write better code. The entire variable lift summarized as follows:

  • var: There is a variable lift, at compile time will be initialized undefined;
  • let: There is a variable lift, there is a temporary dead zone (TDZ), the implementation phase, if not the assignment is initialized undefined;
  • const: There is a variable lift, there is a temporary dead zone (TDZ), if there is no assignment, the compile phase will error;
  • function: There is a variable lift, can be accessed and executed before the variable declaration;
  • class: There is a variable lift, there is a temporary dead zone (TDZ);

Limited capacity, the level of general, welcomed the errata, be grateful.

Subscribe more articles may be concerned about the public number "front-end Advanced Learning ', replies," 666 ", get a package of front-end technology books

Advanced front-end learning

Guess you like

Origin www.cnblogs.com/jztan/p/12349217.html