Introduction to Compilation principles

JavaScript is often categorized as a “dynamic” or “interpreted execution” language, but in fact it is a compiled language. However, unlike traditional compiled languages, it is not compiled ahead of time and the compiled results cannot be ported to distributed systems.

In traditional compiled languages, a piece of source code in a program goes through three steps, collectively known as “compile,” before execution. Word segmentation/lexical analysis Parsing/parsing code generation

Unlike other languages, the compilation process for JavaScript does not take place before build. With JavaScript, most of the time compilation takes place within a few microseconds (or less) before the code executes.

For example, var a = 2; Does the JavaScript engine break it up into several steps? The answer is two steps, which JavaScript treats as two declarations: var a; And a = 2; The first definition declaration is made at compile time, and the second assignment declaration is left in place for execution.

Here’s a breakdown of that statement from the book:

Assignment to a variable performs two actions: first, the compiler declares a variable in the current scope (if it hasn’t been declared before), and then at runtime the engine looks for the variable in the reference field and assigns it if it can find it.

LHS and RHS are the two types of lookups on variables that are assisted by scopes (lexical scopes) and performed in the second step of compilation.

LHSRHS

Left-hand Side (LHS) reference and Right-hand Side (RHS) reference. Usually a reference to the left and right sides of an equal sign (assignment). Let’s look at the following code:

  • The reference to A here is an RHS reference, because there is no value assigned to A, we just want to find and get the value of A and print it out.
console.log(a);
Copy the code
  • Here toaThe quote is oneLHSBecause we don’t care what the current value is,I just want to find the target for the assignment.
a = 2;
Copy the code

Note: the meaning of LHS and RHS for “left and right of assignment operations” does not necessarily mean that this is the left and right of “=”. There are several other forms of assignment, so it is best conceptually understood as “who is the target of assignment (LHS)” and “who is the source of assignment (RHS).”

  • Here’s a more complex example :(find all LHS queries and all RHS queries)
function foo(a) {
	var b = a;
	return a + b;
}

var c = foo(2);
Copy the code

There are 3 LHS queries and 4 RHS queries, and we will analyze all of them:

  • LHS:

    1. Line 6c = ....cIt’s on the left of the assignment, so yeahcNeed to beLHSThe query.
    2. hiddena = 2(implicit variable assignment) in the callfoo(2)Is required to take the argument2Assign to parameter A, so yesaNeed to beLHSThe query.
    3. The second lineb = ..., explain the same as 1.
  • RHS:

    1. Line 6c = foo(2).foo(2)On the right side of the assignment, we need to knowfoo(2)The value of the rightfoo(2)Need to beRHS query.
    2. The second lineb = a.aOn the right side of the assignment, we need to knowaThe value of the rightaNeed to beRHS query.
    3. The third rowreutrn a + b; , need to knowabThe value of, respectivelyaandbbothRHS query.

Summary: If the purpose of the lookup is to assign a value to a variable, then an LHS query is used; If the goal is to get the value of a variable, RHS queries are used.

Importance of distinguishing BETWEEN LHS and RHS

Because the query behavior is different when the variable has not been declared (it cannot be found in any scope).

Both LHS and RHS queries start in the current execution scope, and if needed (that is, they do not find the desired identifier), they continue to look for the target identifier in the upper scope, so that each increment reaches the global scope, stopping whether it is found or not.

Paraphrase a diagram from the book that likens the scope chain to a building. (For an introduction to scope chains, you can move on to JavaScript’s scope chains.)

This building represents a nested chain of scopes in savings. The first floor represents the current execution scope, which is where you are. The top level of the building represents the global scope.

Both LHS and RHS references look up on the current floor, and if they can’t find one, they take the elevator to the next floor, and if they still can’t find one, they go up, and so on. Once you reach the top level (global scope), you may or may not have found the variables you need, but the search will stop anyway.

Summary: Unsuccessful RHS references cause ReferenceError exceptions to be thrown. Unsuccessful LHS references result in either the automatic implicit creation of a global variable (in non-strict mode) that uses the target of the LHS reference as an identifier, or a ReferenceError exception thrown (in strict mode).

The article is reprinted from LHS and RHS queries in ZWKKKK1 -JavaScript