How to quickly get started with VUE3.0: Enter learning
Related recommendations: JavaScript tutorials
We probably often hear "execution environment", "scope", "prototype (chain)", "execution context", etc. What do they describe?
We know that js is a weakly typed language, and the variable type is determined only at runtime. When the js engine executes the js code, it will also perform lexical analysis , syntax analysis , semantic analysis and other processing from top to bottom, and generate an AST (abstract syntax tree) after the code analysis is completed, and finally generate machine code that the CPU can execute based on the AST and execute.
In addition, the JS engine will also perform other processing when executing the code. For example, there are two stages in V8:
This leads to two concepts: "Execution context" and "scope chain".
From the above we can know: when js code executes a piece of executable code, the corresponding execution context will be created.
First of all, there is a concept corresponding to executable code in js: "execution environment" - global environment, function environment and eval
.
Secondly, for each execution context, there are three important attributes:
Let's look at two pieces of code:
var scope="global scope"; function checkscope(){ var scope="local scope"; function f(){ return scope; } return f();}checkscope();
var scope="global scope";function checkscope(){ var scope="local scope"; function f(){ return scope; } return f;}checkscope()();
What will they print?
Why? The answer is that their execution context stacks are different!
What is the "execution context stack"?
When executing an executable code, preparations will be made in advance. The "preparations" here are professionally called "execution context". But with the increase in executable code such as functions, how to manage so many execution contexts? So the JS engine created the concept of execution context stack.
We can completely use an array to simulate its behavior (there is always a global execution context globalContext at the bottom of the stack).
We define an EStack, first
EStack=[globalContext];
and then simulate the first piece of code:
EStack.push(<checkscope> functionContext); EStack.push(<f> functionContext);EStack.pop();EStack.pop();
And the second piece of code is like this:
EStack.push(<checkscope> functionContext);EStack.pop();EStack.push (<f> functionContext);EStack.pop();
The reason is that you may need to study the concept of "closure" first!
By the way, how to achieve "long-term data saving" in "front-end modularization"?
cache? No. Closure!
First of all, scope refers to the area in the program where variables are defined. The scope specifies how to find the variable, which determines the access rights of the currently executing code to the variable.
There are two types of scope: static scope and dynamic scope .
The static scope used by JS is also called "lexical scope". The scope of a function is determined when the function is defined.
From the above, variables in lexical scope will have a certain scope during the compilation process. This scope is the "current execution context". After ES5 we use "lexical environment" instead of scope to describe the execution context. The lexical environment consists of two members:
Let's still look at an example:
var value=1 ;function foo(){ console.log(value);}function bar(){ var value=2; foo();}bar();
Looking back at the above definition, what should be printed?
Let's analyze the execution process:
Execute the foo() function, first search within the foo function to see if there is a local variable value. If not, look for the code on the upper layer based on the position when it was defined, that is, value=1. So the result will be printed as 1.
Of course, this is not so simple and can be summarized. You can analyze it from the perspective of execution context.
Above we talked about the two components of the lexical environment (scope). Combined with the execution context, it is not difficult to find that through the reference of the external lexical environment, the scope can be expanded along the stack layer by layer, establishing a chain structure extending outward from the current environment.
Let’s look at another example:
function foo(){ console.dir(bar); var a=1; function bar(){ a=2; }}console.dir(foo);foo();
From the static scope, the global function foo creates a [[scope]]
attribute of its own object
foo[[scope]]=[globalContext];
and when we execute foo( ), it will also enter the definition period and execution period of the foo function successively. During the definition period of the foo function, the [[scope]]
of the function bar will include the global built-in scope and the built-in scope of foo
bar[[scope]]=[fooContext,globalContext];
This proves this point: "JS will pass External lexical environment references are used to create a scope chain of variable objects, thus ensuring ordered access to variables and functions that the execution environment has access to. "
Let's go back to the question in the execution context, we said earlier. What’s the difference between them? Let’s talk about why they print “local scope” the same way: It’s still the same sentence “JS uses lexical scope, and the scope of the function depends on the location where the function is created” - Execution of JS function A scope chain is used, which is created when the function is defined. The nested function f() is defined in this scope chain, and the variable scope in it must refer to local variables. No matter when and where f() is executed, this binding is still valid when f() is executed.
When a variable cannot be found in its own lexical environment record, it can be searched to the outer layer based on the external lexical environment reference until the external lexical environment reference in the outermost lexical environment is null
.
Similar to this is "search based on prototype chain in objects":
__proto__
is null). The difference is also obvious: the prototype chain is a link that establishes object inheritance through the prototype attribute; while the scope chain refers to the closure that allows internal functions to access external functions. Whether directly or indirectly, all function scope chains ultimately link to the global context.
Related recommendations: JavaScript learning tutorial.
The above is an in-depth understanding of how the JavaScript engine executes JS code. For more information, please pay attention to other related articles on the PHP Chinese website!