Scope exists as a most basic function in various programming languages, which makes our programming more flexible and interesting. Its basic function is to store the value in the variable, and then the value can be accessed and modified.
Maybe we all know some concepts of scope, as well as some of its extended content closures, etc., but compared with these possibilities, we need to understand where these variables are stored, and How our program accesses them will be more interesting.
var a = 1;
First of all, we need to understand who participates in our entire process when we declare variables and assign values.
1. Engine: It participates in the compilation and execution of the entire JS program.
2. Compiler: It is responsible for syntax analysis and code generation.
3, Scope: It is responsible for mobile phones and maintaining a series of queries composed of all identifiers (variables), and has implemented a very strict set of rules to determine The currently executing code has access to these identifiers.
When the engine sees var a =1;, it is different from what we think. We think it is a statement. What it actually thinks is that there are two completely different statements. One is The compiler handles it at compile time, and the other is handled by the engine at runtime. So let's see how they work.
The compiler will first decompose var a = 1; this program into lexical units, and then parse the lexical units into a tree structure, but when the compiler starts to generate code, it will will be handled differently.
In the scope of our understanding, the compiler works like this: allocate memory for a variable, name it a, and then save the value 1 into this variable, but the reality is different.
1. When encountering var a, the compiler will first ask the scope whether there is already a variable with this name in the collection of the same scope. If so, the compiler will ignore the declaration and continue compilation, otherwise it will ask the scope to declare a variable named a in the collection of the current scope.
2, then the compiler starts to generate the code required for the engine to run, which will be used to handle the assignment operation of a = 1. Then when the engine runs, it will first ask the scope whether there is a variable called a in the current scope set. If so, the engine will use this variable. If not, the engine will continue to search for the variable in the upper-level scope of the current scope. variable. Finally, as long as a is found, the engine will assign 1 to it. If it is not found, the engine will throw an exception.
So: There are two operations in the assignment of a new variable. The first is that the compiler declares the variable, and the second is that the engine finds the variable in the scope and assigns a value to it.
Look at a simple code below
function demo(a){ console.log(a) } demo(2);
Before continuing, let’s take a look at LHS and RHS. As the name suggests, one is left and the other is right. These are the two queries used by the engine for variables. L and R represent the left and right sides of an assignment (in most cases). That is to say, an LHS query is performed when a variable appears on the left side of an assignment. RHS query when on the right. But a more accurate statement is that the RHS query simply finds the value of a variable, while the LHS query finds the container itself of the variable and assigns it a value. So according to this statement, we can find that RHS actually represents "non-left side". Let's look at a simple code.
var a = 1; console.log(a);
在上面的代码中,var a =1;对a的引用是一个LHS引用,而console.log(a)的a其实就是一个RHS引用。再看一个例子:
function demo(a){ console.log(a); } demo(1);
上面的代码中其实包含了RHS和LHS引用。我们理解下demo(1);的意思,它其实意味着RHS引用demo这个值,(...)意味着它需要被执行,而在执行的过程中,有一个隐式的LRS引用 a = 1; 这个查询发生在参数传递的过程中。其中的console.log(a)也是个RHS引用。
同时我们需要知道,不成功的RHS会导致抛出一个异常,而不成功的LHS引用会导致自动隐式的创建一个全局变量(非严格模式),或者抛出异常(严格模式)。
当一个块或者函数嵌套在另一个块或者函数内时,就发生了作用域的嵌套。因此,当在当前作用域中无法找到该变量时,引擎就会在外层嵌套的作用域中继续查找(若一直没有找到会到达全局作用域),直到找到该变量。
上图一层一层往外形成的结构就是我们常说的作用域链,最内层代表当前执行环境的作用域,最外层代表全局作用域。LHS和RHS都会在当前作用域进行查找,如果没有找到,就会向外,以此类推,如果到达全局作用域都没有找到,那无论如何这个查找过程都会停止。
The above is the detailed content of Parsing the scope and assignment operations of Javascript. For more information, please follow other related articles on the PHP Chinese website!