A detailed introduction to the scopes in JavaScript _javascript tips

Source: Internet
Author: User
Tags throw exception

1, the principle of compiling

In a traditional compiled language process, a piece of code in a program goes through three steps before it executes. Collectively referred to as "compilation."

Lexical analysis

Break code strings into meaningful blocks of code called lexical units. For example: In JS, var a = 2;. This procedure is usually split into the following lexical units. Var, a, 2,;. Whether the space will be treated as a lexical unit depends on whether the space has meaning in the language.
Grammar analysis
Converts a lexical cell stream (array) to an abstract syntax tree (ast,abstract Syntax). Compiled principles mentioned in the course).
Code generation
Converts the AST to executable code. Language, platform-related (Java cross-platform). In simple terms: the ast of var a = 2 is converted to a set of machine instructions for creating a variable (allocating memory, etc.) and storing 2 in a.

For JavaScript, though it is often categorized as a "dynamic" or "interpreted execution" language, it is actually a compiled language. The difference is that when it compiles, the engine performs more complex operational procedures.
First, the JavaScript engine does not have a lot of time to optimize (as much as other compilers), because unlike other languages, its compilation process is not built before.
For JavaScript, most compilations occur a few microseconds (or even shorter) before the code executes. So the engine uses a variety of methods (such as JIT) to ensure the best performance.
Simply put, any JS code must be compiled (several microseconds ago) before it is executed. Therefore, before executing var a = 2, the engine compiles and is ready to execute it (join the code queue). It is usually done immediately.

2. Understanding Scopes

Engine
Responsible for the entire compilation and execution process.
Compiler
One of the best friends of the engine, responsible for the syntax analysis and code generation and other dirty live dirty.
Scope
Another good friend of the engine is responsible for collecting and maintaining all variables and implementing a very strict set of rules to ensure that the current code (scope) accesses the variable.

for var a = 2, it's not just a simple statement. Declares that it has two processes. Compile-time: The compiler carries out related operations. When executing, the JS engine performs the related operation.

var A, the compiler will look for a variable in the current scope. If it does, the compiler ignores this declaration. Otherwise, create a variable (allocate memory) in the current scope.

A = 2, then the compiler (parsing, code generation ...) The code needed to generate the runtime is used to handle this assignment operation. The specific assignment operation is handled by the JS engine. The JS engine looks for a variable in the current scope and, if found, assigns the value. Otherwise, lookup in the parent scope (scope nesting), up to the global scope. If found, perform an assignment operation. The throw exception could not be found.

In the search for scopes, LHS queries and RHS queries are involved. They represent the target of the assignment operation and the source of the assignment operation, respectively. Not only assignment operations, but also function assignment operations, and so on. Like what:

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

The last line of the Foo () function call requires a RHS query on the foo () itself. The claim for Foo is found in the global scope. and () means to execute Foo as a function, so foo is best a function, otherwise it will be an error.

There is also an easy to overlook the details. When you pass 2 as an argument to the formal parameter of Foo, there is an implicit a=2 action. A is the source of the assignment operation, and 2 is the target of the assignment operation. So here's a LHS query for a. Because a is declared as a formal parameter of Foo at the current scope (function scope) during compilation, it can be found.

Then there is console.log (a); the console itself needs a LHS query, which is a built-in object under window, so it can be found. Then make a RHS query for a. Luckily, a has already been declared and assigned a value when assigning 2 to function parameter A. So this RHS can be done.

3, scope nesting

As we said before, scopes are responsible for collecting and maintaining all variables and implementing a very strict set of rules to ensure that the current code (scope) accesses the variable. Consider the following code:

function foo (a) {
  console.log (a+b);
}
var b = 2;
Foo (2);

We only consider the RHS reference to B here. The JS engine started trying to find B variables in the Foo function scope, but was not found. As a result, the JS engine will break through the current limit, to the outer scope lookup. Oh, I found it! So the RHS reference to B was successful. Of course, if not found, the JS engine will not give up, will continue to look for the outer scope until the global scope is found. Then follow the rules that refer to the a=2 assignment.

4, abnormal

In the case where a variable has not been declared (no scope can be traced), the operation of the LHS and RHS query fails. It can be expected that RHS query failure throws an exception, then LHS query fails?

function foo (a) {
  console.log (a+b);
  b = A;
}
Foo (2);

The declaration of a variable cannot be found in any scope when a RHS query is first made to B. Then have a small partner to doubt, B=a? Not a statement to B? The answer is: yes. This is indeed a statement to B.
However, in the process of looking up a scope, only the declaration is looked up (involving a claim elevation). Because b here is defined after Console.log (). So it is the failure to throw the Referenceerror exception. It is noteworthy that Referenceerror is a very important type of exception. Consider the following code:

function foo (a) {
  b = A;
  Console.log (a+b);
}
Foo (2);

Here, for the first time, a LHS query is made for B. If Foo is not found in the top-level (global) scope, then the JS engine will be very enthusiastic to help you create a B variable in the global scope, provided that the code "use strict" is added to a scope in a domain other than "strict mode", indicating that strict mode is used. In strict mode, when a LHS query fails, it does not create a global variable, but rather throws a Referenceerror exception similar to the RHS query failure.
Next, join you to find the variable, but you try to make an unreasonable operation on the variable. For example, a variable of a non function type () function call, a value of null or undefined type is accessed, the engine throws another type of exception, called TypeError.
In a word, the refercenerror is related to the scope discriminant failure, while the TypeError indicates the success of the scope, but the operation of the result is illegal.

5. Summary

A scope is a set of rules that specify where and how to look for variables (plus the important things mentioned before, say three times). If the purpose of the lookup is to assign a value, it is a LHS query. If the purpose is to get the value of the variable, a RHS query is made.
The JS engine compiles the code before it executes. var a = 2, such an operation is divided into two steps.
1. At compile time, the compiler declares a variable, that is, var a.
2. At run time, assign values to a variable. a=2.
LHS queries and RHS query failures do different things. RHS query failure throws Referenceerror exception. LHS query Failure creates a variable (not strict mode) in the global scope and throws a Referenceerror exception in strict mode.

The above is the entire content of this article, I hope to help you, I hope you will continue to pay attention to the latest content of the cloud-dwelling community.

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.