In-depth understanding of the JavaScript Scope series first-internal principles

Source: Internet
Author: User

xDirectory [1] compilation [2] execution [3] query [4] nesting [5] exception [6] in front of the principle

JavaScript has a well-designed set of rules to store variables, which can then be easily found, a set of rules called scopes. The scope seems simple, but complex, because the scope and this mechanism is very easy to confuse, make understanding the principle of scope is more important. This article is the first in-depth understanding of the JavaScript Scope series-Internal principles

The internal principles are divided into five parts: compilation, execution, query, nesting and exception, and the principle is explained by an example process.

Compile

Take var a = 2; For example, the internal compilation process of JavaScript, mainly includes the following three steps:

"1" participle (tokenizing)

Break up a string of characters into meaningful blocks of code called Lexical units (tokens)

var a = 2; is decomposed into the following lexical units: var, a, =, 2,; These lexical units form an array of lexical cell streams

"2" parsing (parsing)

The lexical unit stream array is transformed into a tree representing the syntactic structure of the program, which is called "Abstract Syntax Tree" (AST), which is composed of nested elements.

var a = 2; there is a top-level node called variabledeclaration in the abstract syntax tree, followed by a child node called identifier (whose value is a), and a child node called Assignmentexpression. And the node has a child node called numericliteral (whose value is 2)

"3" code generation

The process of converting an AST to executable code is called code generation

var a=2; The abstract syntax tree is converted to a set of machine instructions to create a variable called a (including allocating memory, etc.) and store the value 2 in a

In fact, the JavaScript engine's compilation process is much more complex, including a lot of optimizations, and the three steps above are a basic overview of the compilation process

Any code fragment is compiled before execution, and in most cases the compilation occurs in microseconds before the code executes. The JavaScript compiler first a=2 the Var, the program compiles, then prepares to execute it, and usually executes it immediately.

Perform

In short, the compilation process is the compiler to decompose the program into lexical units (tokens), and then parse the lexical unit into a syntax tree (AST), and then turn the syntax tree into a machine instruction waiting for execution of the process

In fact, the code is compiled and executed. The following is still a var a = 2; for example, an in-depth explanation of the compilation and execution process

"1" compilation

1. The compiler looks for scopes that already have a variable called a that exists in the same scope's collection. If so, the compiler ignores the declaration and continues compiling, otherwise it will require the scope to declare a new variable in the current scope's collection and name a

2. The compiler will var a = 2; This code fragment is compiled into a machine instruction for execution

[note] According to compiler compiler principle, the duplicate declaration in JavaScript is legal

// test appears for the first time in the scope, so declare a new variable and assign 20 to test var test =; // test already exists in scope and is used directly to replace the 20 assignment with the value of var test = 30;

"2" execution

1. When the engine runs, the scope is queried first, and there is a variable called a in the current scope collection. If so, the engine will use this variable, and if no, the engine will continue to look for the variable

2. If the engine finally finds the variable A, it will assign the value of 2 to it. Otherwise the engine throws an exception

Inquire

In the first step of the engine execution, the variable A is queried, and the query is called a LHS query. In fact, engine queries are divided into two types: LHS queries and RHS queries

To understand the literal meaning, when the variable appears to the left of the assignment Operation LHS Query, appear on the right when the RHS query

More precisely, the RHS query is no different from simply finding the value of a variable, while the LHS query is an attempt to find the container itself of the variable so that it can be assigned a value

function Foo (a) {    console.log (a); // 2  2);

In this code, a total of 4 queries are included:

1. Foo (...) RHS a reference to Foo

2. function parameter A = 2 a LHS reference to a

3, Console.log (...) A RHS reference to the console object and check if it has a log method

4, Console.log (a) a RHS reference to a, and the resulting value passed to the Console.log (...)

Nesting

When a variable cannot be found in the current scope, the engine continues to look in the outer nested scope until the variable is found, or the outermost scope (that is, the global scope) is reached

function Foo (a) {    + b);} var b = 2; foo (2); // 4

In the code snippet, the scope foo () function is nested in the global scope. The engine first looks for the variable B in the scope of the Foo () function and attempts to RHS it, not found; Then, the engine looks for B in the global scope, finds it successfully, RHS a reference to it, and assigns a value of 2 to B

Abnormal

Why is it important to differentiate between LHS and RHS? Because the variables are not declared (variables cannot be found in any scope), the behavior of the two queries is different

RHS

"1" If the RHS query fails, the engine throws an Referenceerror (reference error) exception

// the variable cannot be found when a RHS query is made on B. In other words, this is an "undeclared" variable function  foo (a) {    = b;  } Foo (); // referenceerror:b is not defined

"2" If the RHS query finds a variable, but attempts to unreasonably manipulate the value of a variable, such as a function call to a non-function type value, or reference a property in null or undefined, the engine throws another type exception: TypeError (type error) exception

function foo () {    var b = 0;    b ();} Foo (); // typeerror:b is not a function

LHS

"1" When the engine executes a LHS query, if the variable cannot be found, the global scope creates a variable with that name and returns it to the engine

function foo () {    = 1;  } Foo (); Console.log (a); // 1

"2" If the LHS query fails in strict mode and does not create and return a global variable, the engine throws a Referenceerror exception similar to the RHS query failure

function foo () {    ' use strict ';     = 1;  } Foo (); Console.log (a); // referenceerror:a is not defined

Principle
function Foo (a) {    console.log (a);} Foo (2);

The code snippet above illustrates the inner workings of the scope, divided into the following steps:

The "1" engine needs to be foo (...) The RHS function makes a reference to find Foo in the global scope. Successfully found and executed

The "2" engine needs to pass the parameter a=2 of the Foo function, lhs a reference to a, and find a in the Foo function scope. Successfully found and assigned 2 to a

The "3" engine needs to perform a console.log (...) to make a RHS reference to the console object and find the console object in the Foo function scope. Because the console is a built-in object, it is successfully found

The "4" engine looks for the log (...) in the console object. method to successfully find

The "5" engine needs to execute Console.log (a), RHS a reference to a, find a in the scope of the Foo function, and successfully locate and execute

"6" Then, the engine to the value of a, that is, 2 to Console.log (...) In

"7" Finally, console output 2

In-depth understanding of the JavaScript Scope series first-internal principles

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.