You do not know the volume of JavaScript 2/11

Part I - scope and closure

Chapter One

What scope is

1. One of the most basic functions of almost any programming language, which is the ability to store the value of a variable, and after this value can be accessed or modified. In fact, it is this ability to store and access the value of the variable will be the state brought the program.

2.JavaScript with traditional compiled languages, it is not compiled in advance, compile the results can not be transplanted in a distributed system.

3. The process of traditional compiled languages, compilers, "three steps"

   * Word / lexical analysis

  Character string will be decomposed into (for programming language) meaningful block (referred to as lexical units token). E.g. var a = 2; is decomposed into var, a, =, 2 ,;

   * Parsing / syntax analysis

  The flow lexical unit (array) into a nested cascade elements composed of the tree represents the syntactic structure of the program (abstract syntax tree Abstract Syntax Tree, AST). The var a = 2; abstract syntax tree node may have called VariableDeclaration top, followed by a known Identifier (value of a) a child node, the child node and the called AssignmentExpression. AssignmentExpression node has child nodes called NumericLiteral (value 2)

   * Code Generation

  The AST is converted to executable code process. The AST is converted to a set of machine instructions to create a named variable, and a value stored in a.

Compared to only three steps compiler language, js engine is much more complex.

4. understand the scope of this process can be modeled as a dialogue between several tasks.

  * Engine responsible for compilation and execution process from start to finish the whole program of JavaScript

  * One good friend compiler engine is responsible for parsing and code generation dirty work

  * Another good friend scoping engine, responsible for collecting and maintaining a series of queries by the identifier (variable) consisting of all declared and implemented a set of very strict rules that determine the code currently executing access to these identifiers .

The assignment of variables performs two actions, first compiler (if declared useless before too), then the engine will look for the variables in scope at run time, if they could declare a variable in the current scope it will be assigned to it.

The second step, the engine has two search methods. LHS with RHS. As the name suggests, LR represents the left side, right side.

LHS (who is the target of an assignment), RHS (who is the source of an assignment) is simply the right LHS of an assignment on the left side of an assignment RHS

For example function foo (a) {

    console.log(a);//2

}

  foo(2);

The case a = 2, a target of the operation is assigned to be a LHS, where 2 is the parameter passed in the implicit allocation, foo (...) is the source of the assignment of all RHS, means "to find the foo value, and give it to me, "there is a console.log (..) itself requires a reference to perform, but also on the RHS of a reference.

For example function foo (a) {

    var b = a;

    return a + b ;

}

  var c = foo (2);

Excerpt written by someone else to see what good microblogging resolution

The above code has three to four LHS RHS, as follows:

First, the var c c needs to be assigned, the assignment on the left side, so the reference c for LHS

Second, the variable c needs to be assigned, his value is foo (2), then foo (2) value is how much, you need to find the value of foo (2), the right side of the assignment, so the foo (2 ) were cited RHS

Third, implicit assignment, 2 passes to function foo (a) {......} function of a parameter, a left side of the assignment, to be a reference LHS

Fourth, var b = a;, b is to be assigned, at the left side of the assignment, so the value of LHS b carried out, b from a to, then the value of a right side come from? This requires the assignment of a right side of the operation carried out RHS.

Fifth, return a + b;, we need to find the source of the value of a and b, a and b are on the right side of an assignment, to get the value of a + b, so a and b are carried out on the RHS reference.

 6. When a function block or nested within another block or function, occurred nested scopes.

  LHS and RHS references will look in the current scope, if not found, will look to higher scopes until global scope. To the global scope, the search process will stop anyway.

7. Why distinguish between LHS and RHS is an important thing

 

function foo(a){
        console.log(a+b);
        b = a;
        c = {};
        console.log(c.list.name);
}
foo(2);

The first time to be b RHS inquiry can not find the variable. That "undeclared" variables in the query all nested scopes can not be found, engine throws an error ReferenceError.  

 

 

 

Under comparison, LHS query, if the global scope can not find the target variable, global scope will create a variable with that name, and returns its engine, the premise wrong, "strict mode."

If the query to the RHS variable, but the variable is unreasonable operation. For example, a non-function type value of a function call, or a reference to the attribute value of null or undefined type, throw TypeError , of course, the above first deleted and then b RHS of erroneous operation, since the implementation is not deleted By the time the first query had been wrong not to execute the next.

 

 

 

 

 

 

Chapter two

 

Lexical scoping

 

1. Scope There are two main working model. The first most common, is used by most programming languages, lexical scoping. Another called dynamic scoping.

 

2. deceive lexical.

 

eval js in (..) function accepts a string as a parameter, and the contents treated as if it is the same as that at the time of writing, the engine does not know or care whether the code is inserted in a dynamic form, will as usual Like to find out.

 

 

function foo(str,a){
        eval(str);//欺骗!
        console.log( a, b);
  }
var b = 2;
foo ( "var b = 3;" , 1); // 1,3

 

the eval (..) is often used to execute code dynamically created.

Note: In strict mode, has its own lexical scope, meaning that eval can not be modified at runtime.

            function foo (str){
                "use strict"
                eval( str );
                console.log( a );
            }
            foo ( "var a = 2");

 

 

with simplified object property assignment

        function foo (obj) {
             with (obj) { 
                A = 2 ; 
            } 
        } 
        var O1 = { 
            A: . 3 
        }; 
        var O2 = { 
            B: . 3  
        }; 
        foo (O1); 
        the console.log (o1.a); 
        foo (O2); 
        the console.log (o2.a); 
        the console.log (o2.b); 
        the console.log (A); // A global variable leakage

Here's why a leak as a global variable is mainly in non-strict mode, the call to foo (o2) a 2 looks for the LHS of =, can not find, and then define a search for a global variable. Try the following results foo (o2) after deletion.

 

 

 

 

Side effects of these two mechanisms is that the engine can not find the scope optimization at compile time; because the engines can only caution that such optimization is invalid. Use any one of these mechanisms will lead to code run slower. So it is best not to use them.

 

Guess you like

Origin www.cnblogs.com/ljg1998/p/12615370.html