The example of this article analyzes the use of JavaScript scoped chain (scope Chain). Share to everyone for your reference, specific as follows:
About the scope of JS chain, has been heard, and have seen several introductory blog, but has always understood the ambiguity. Recently and carefully looked at the "Understanding through JavaScript" This book, feel too Deep, in the "Code of Time and Space" section of a paragraph to introduce the scope of the chain of a few words, memorable (in fact, or understanding the ambiguous ^_^). Now tidy up their own reading notes, by the way to learn from online resources, write down.
First, from a simple question.
The following JS code runs on the page to show what results:
var arg = 1;
function Fuctest (ARG) {
alert (ARG);
var arg = 2;
Alert (arg);
}
Fuctest (10);
What is your answer? Yes, just pop 10. My understanding is that the Funtest function has a formal parameter arg,funtest function to pass in the argument 10,alert method to eject the 10 is, embarrassed.
Well, here's the problem again:
var arg = 1;
function Functest () {
alert (ARG);
var arg = 2;
}
arg = ten;
Functest ();
What's the answer? If it is 5 years ago I, certainly will not further down thought, or 10! What do you think of such a simple question? My understanding is this: the Funtest function is a function without parameters, the function of the internal through the alert method, call the external (global) variable arg, before the function execution, arg assignment is 10, after the ARG value to change the arg value of 2, so the pop-up value of 10.
Is it really 10? Yes, or not?
Test results: Pop-up "undefined", Waterfall Khan.
Second, understand the scope chain, from the JavaScript operating mechanism to talk about
1, the operation of JS order
If a document flow contains multiple script snippets (JS code separated by a script label or a JS file that is introduced), they run in the following order:
Step 1. Read the first code snippet (the JS execution engine does not execute the program in one line, but a section of the execution)
Step 2. Do a grammar analysis, the error of the report syntax errors (such as parentheses do not match, etc.), and jump to step 5
Step 3. "Pre-resolution" for VAR variables and function definitions (never error, because only correct declarations are parsed)
Step 4. Execute code snippet, error errors (such as variable undefined)
Step 5. If you have the next code snippet, read the next code snippet, repeat step 2
Step 6. End
The above analysis is clear enough, the red font in steps two or three and four may be a blind spot for our novice to understand, especially step three, "pre-resolution," If not clear what is called pre-resolution, always feel not practical. and step four "error is wrong" is often encountered. For example:
function Functest () {
alert (ARG);
var arg = 2;
}
Functest ();
The above code executes, pop-up "undefined", that is, ARG does not define, JS variables are not defined also can it?
2, syntax analysis and "pre-resolution"
(1), from the interpretation of the language of the compilation process
As we all know, JavaScript is an interpretive language, unlike compiled languages like C # and Java. For the traditional compiled language, the compilation steps are divided into lexical analysis, syntax analysis, semantic checking, code optimization and byte generation, but for interpreted language, the syntax tree can be explained by lexical analysis and grammatical analysis.
A, lexical analysis
In a nutshell, lexical analysis converts a character stream (char stream) to a token flow (token stream).
But the conversion process is not as simple as a single sentence, we can try to understand a simple program with pseudocode:
The conversion of code VAR result=x-y can generally be expressed as follows:
NAME "Result"
EQUALS
NAME "X"
Minus
NAME "Y"
Semicolon
B, Grammar analysis
To put it simply, parsing is to construct a legal parsing tree, and the parse tree can visually express the derivation process.
So what is a parse tree? To put it simply, it is the description of the process of deducing the program. But in the end what is the syntax tree, please refer to the professional article, this article skip.
C, other
After parsing, the syntax analysis tree is constructed, and further semantic examination may be required. For traditional strongly typed languages, the main part of semantic checking is type checking, such as whether the arguments of the function and the formal parameter types match.
Conclusion: It can be seen from the above analysis, for JavaScript engine, there must be lexical analysis and syntax analysis, and then there may be semantic check, code optimization and other steps, such as the completion of these compilation steps ( any language has a compilation process, but the interpretation of the language is not compiled into binary code ) before the execution of the code begins.
(2), the implementation process
A, the scope mechanism of JavaScript
By compiling, JavaScript code has been translated into a syntax tree and then executed immediately according to the syntax tree.
For further execution, you need to understand the scope mechanism of javascript: lexical scopes (lexcical scope). In layman's terms, the scope of a JavaScript variable is determined when it is defined rather than executed, meaning that the lexical scope depends on the source code, and the compiler is able to determine by static analysis , so the lexical scope is also called a static scope (field static scope). It should be noted, however, that thesemantics of with and Eval cannot be implemented only through static technology, so the JavaScript scope mechanism is very close to the lexical scope (lexical scope).
The JavaScript engine creates an execution environment (execution context) when it executes each instance of the function. The execution environment contains a calling object (Call object), which is a scriptobject structure (ScriptObject is a static system associated with a function that is consistent with the life cycle of the function instance) and is used to hold the internal variable table VARDECLS, Syntax analysis constructs such as inline function table FUNDECLS, parent reference list Upvalue (note that information such as VARDECLS and FUNDECLS are already available in the parsing phase and stored in the syntax tree.) When a function instance executes, the information is copied from the syntax tree to the ScriptObject.
b, the implementation of JavaScript scope mechanism
The lexical scope (lexical scope) is the scope mechanism of JavaScript, and it also needs to understand how it is implemented, that is, the scope chain (scope chain). The scope chain is a name lookup mechanism that is first sought in the scriptobject of the current execution environment, and is not found, followed by Upvalue to the parent ScriptObject lookup to the global object.
Now go back and analyze the second question:
var arg = 1;
function Functest () {
alert (ARG);
var arg = 2;
}
arg = ten;
Functest ();
When the Functest function is executed, the corresponding scope of the functest is entered, and when the JS engine is executed, when it encounters the use of variable name or function name, it first looks for the variable or function in the current scope (that is, the functest corresponding scope) (Obviously, The arg variable is defined as Var arg=2 in the corresponding scope of the functest, so the parameters of the alert method take the arg of the current scope, but because ARG is defined after the alert method, the ARG variable defaults to undefined. Of course, if you don't find it, go to the upper scope lookup, and so on (the scope can persist to the root of the JavaScript Runtime Environment: Window object).
Finally, let you see more clearly that the above code can actually be equivalent to:
var arg = 1;
function Functest () {
var arg;//default value undefined
alert (ARG);
arg = 2;
}
arg = ten;
Functest ();
C, closure (closure)
When a function instance is executed, it is created or associated to a closure. (about closure, I'm going to write another study note)
ScriptObject is used to statically save variable tables related to functions, and closures dynamically save these variable tables and their operating values during the execution period;
The life cycle of a closure may be longer than a function instance. A function instance is automatically destroyed when the active reference is empty;
Closures wait for the data reference to be empty, reclaimed by the JavaScript engine (in some cases not automatically recycled, resulting in a memory leak).
PS: About the "execution process" this paragraph is a bit awkward, a lot of nouns, but don't be intimidated by them, once you understand the execution environment (execution context), Invoke object (call objects), lexical scope (lexical scope), scope chain (scope Chain), closures (closure) and so on these concepts, JavaScript many phenomena can be solved.
Third, the conclusion
Through the second paragraph of analysis, compared to the first paragraph of the author has made judgments (you are not also think that the author once analysis and conclusion is very naïve (even if sometimes the results happen to be right!) )?! Not a general superficial ah, ^_^), you will find that the original JavaScript there are so many "mystery", but to really understand the proficiency is not easy? First "get through".
I hope this article will help you with JavaScript programming.