Preface:
In my opinion, JavaScript is a very loose and flexible language, which is not derogatory. On the contrary, JavaScript is a kind of praise. Compared with the static compilation languages such as C #, JavaScript is like a naughty child who is already very skilled in cycling. He no longer needs to follow the principle that he must help the handlebar on the right of the car, he can make a number of different fancy moves, but he will never deviate from the balance principle. The flexibility in the formal form even seems a little weird, making JavaScript and the C # language incompatible: It is object-oriented, but there is no class, can inherit and create a prototype, the concept of "This" is even more confusing.
But don't forget that we think Javascript is weird just because we are used to C-language thinking. JS is still a computer language, just as the fancy cycling boy does not deviate from the "balance" principle, JS does not deviate from one principle of computer language (just like other computer languages ): control the computer to do things.
From another perspective, it is precisely because of the flexibility and strangeness of JS that we should learn in depth like other static languages. Under the guidance of the principle of "learning another quite different language", it is very valuable to study Js in depth. Learning JS can enable us to understand computer languages and programming from a very different way of thinking from C # Java, and to understand the core things and ideas that keep changing.
When I was learning JavaScript, I naturally got confused about many concepts. Although I had a lot of tutorials on the Internet that "deeply understood JavaScript XXX", I always felt that it was not deep enough, it's just as easy as asking others what their stacks are, and others just tell you to "come first.
But fortunately, a few days ago I finally found a series of blog tutorials written by Russian Dmitry soshnikov: "ECMA-262-3 in detail", there is also a wonderful "official translation" in the garden. This series of blogs is really very useful. From the perspective of ECMA norms, parsing JS is more in-depth and thorough, and covers all the advanced topics of Js. However, although this series of blogs is well written and the examples are appropriate, they all describe more advanced content in JS, so it is difficult to understand many points immediately, I need to read and consider it over and over again. Therefore, this blog post is my notes during my learning process. I can record some of my experiences and other things that need to be remembered at any time.
Chapter 1:Execution contexts
The execution context will also be generated when the function is called recursively.
Execution context is the logical stack structure
Chapter 2: Variable object
Even variables declared in the else branch that will never be executed, or function definitions, will be stored in vo.
VO In function is called activation object (AO), while vo in global is also called Global. Vo is just a general name.
Scope chain = List of parent's vos + function's own AO
In addition, there is a phenomenon that may be related to one sentence:Activation objectIs created on entering the context of a function and initialized by propertyarguments
Which value isArguments object:
This phenomenon is: if a function declares a variable and the variable name is the same as the name of the function's form parameter, the variable and the form parameter are actually the same thing, example:
Function Foo (I ){
VaR I = 5;
Alert (arguments [0]);
}
Foo (10); // 5 instead of 10
The opposite is true:
Function Foo (I ){
VaR I;
Arguments [0] = 10
Alert (I );
}
Foo (5); // 10 instead of 5
As for whether the underlying implementation is like this, it is still being studied, but it seems that it can be resolved in this way.
Chapter 3: This.
Identifier is the variable name. Function Name (for example, "foo" in function Foo () {}, function parameter name and unknown attribute in global)
There are only two types of reference: identifier processing and attribute accessors. The property accessors are "." and "[]", such as "obj. foo" and "OBJ [" foo "]".
The base attribute of the reference type points to the owner of the object.
Chapter 4: Scope chain.
"Scope" is actually [Scope]. Generally, scope refers to the [[Scope] attribute of the function object, the scope chain refers to the [[Scope] linked list in the function object (of course not necessarily the linked list structure)
[[Scope] is created when a function is created, instead of when a function is executed (into execution context), and it is not changed during function execution, therefore, there is a closure mechanism:
VaR x = 10;
Function (){
Alert (X );
}
Function B (){
VaR x = 20;
A ();
}
B (); // 10 instead of 20
Chapter 6: Closure
It is a little difficult to parse the closure now, because to clarify the closure, we must understand scope/scope chain and context, and the inverse is associated with the previous chapters, to parse the closure in detail, you may need to write more complete notes. Now, let's take a note of some fragmented understandings. It will be used in any case. Let's take a look at a typical closure example:
Function Foo (){
VaR x = 10;
Return function (){
Alert (X );
}
}
VaR bar = Foo ();
Bar (); // 10
If it is not a closure, logically, X is a local variable in Foo. After Foo returns the result, X has been released. The closure is a mechanism that can still access the internal data of the function after the function is returned. In principle, the scope of the called function (the anonymous function in Foo) contains the data of the external function (FOO, this is more general, because I still don't know what this should be, is it VO? I will study it later), but from the scope level, it is because "JS is based on static scope", so there is a sentence in ecmascript in detail: referencing to algorithm of functions creation, we see that all functions in ecmasres are closures, since all of them at creation save scope chain of a parent context. (All functions in ecmascript are closures)
Here we must look at "dynamic scope" and "static scope ". Let's take a look at an example:
// Suppose this is global.
VaR x = 5;
Function Foo (){
Alert (X );
}
Function bar (){
VaR x = 10;
Foo ();
}
Bar (); // 5 instead of 10
Static scopes, which are called lexical scopes in some cases, mean that a scope is fixed when a function is created, rather than executed. You can also say that the function scope is determined in the source code.
Through the above example, let's see what this "determining in the source code" means: In the above example, when bar is called, it enters the bar context, and the bar declares an X, assign a value of X = 10 and then call Foo. If it is a dynamic scope, that is, to determine the scope at the time of code execution, then the Alert X in Foo should be X in bar, that is, 10, but under the principle of static scope, "the function scope is determined in the source code", that is, when foo is called, the parsing engine will go back to the place defined by foo (the first four sentences in the source code), and here, it is obvious that X is the X whose value is 5 defined by the source code in the first sentence, in addition, in the source code defined by Foo, X with the value of 10 has not yet been generated ~~~. This is my own understanding of "static scope", but I don't know much about dynamic scope. I have time to look at dynamic scope on Wikipedia.
Here, by the way, the C language is also a static scope:
# Include "stdafx. H"
Int x = 5;
Void fun1 (){
Printf ("% d", X );
}
Void fun2 ()
{
Int x = 10;
Fun1 ();
}
Int _ tmain (INT argc, _ tchar * argv [])
{
Fun2 (); // 5
Scanf ("% d", & X );
}
Ecmascript only uses static scopes (syntax scopes)
In ecmascript, the closure refers:
Theoretically: All functions. Because they all save the upper-layer context data when they are created. This is true even for simple global variables, because accessing global variables in a function is equivalent to accessing free variables. In this case, the outermost scope is used. From a practical perspective: The following functions are regarded as closures: 1. even if the context to be created has been destroyed, it still exists (for example, internal functions are returned from the parent function. A free variable is referenced in the code.