Home >Web Front-end >JS Tutorial >Introduction to using JavaScript scope chain_javascript tips

Introduction to using JavaScript scope chain_javascript tips

WBOY
WBOYOriginal
2016-05-16 17:24:091047browse

I have written an article before about What exactly is a JavaScript closure? about understanding closures. I think it is very clear and I can easily understand the reasons for closures. However, I read the comments and they all say that I understand the scope. Only chains and active objects can truly understand closures. I didn't think so at first. Later, when I communicated with colleagues in the company, I found that scope and execution environment are indeed very important and very basic. They are very helpful for understanding JavaScript closures, so I wrote an article about them. Understanding of scope and execution environment.

Scope

Scope is the accessible scope of variables and functions, which controls the visibility and life cycle of variables and functions. In JavaScript, the scope of variables has global scope and local scope.

Pure JavaScript scope is still easy to understand. In some C-like programming languages, each piece of code within curly braces has its own scope, and variables are invisible outside the code segment where they are declared. This is the block-level scope, and this is where JavaScript easily misunderstands beginners. JavaScript does not have block-level scope, only function-level scope: variables are visible within the function body and sub-functions in which they are declared. .

A variable that is not declared within a function or declared without var is a global variable. It has a global scope. All properties of the window object have a global scope; it can be accessed anywhere in the code. It is declared inside the function and decorated with var. The variables are local variables and can only be used within the function body. Although the parameters of the function do not use var, they are still local variables.

Copy code The code is as follows:

var a=3; //Global variable
function fn(b){ //Local variable
                                                                                                                  var e=d; / /Local variables of the parent function are visible to the child function                 alert(i);/ /3, Declared within the for loop, it is still visible in the function outside the loop, and there is no block scope
                                                                                                                                                                                                                                                                       ; Global variables



As long as you understand that JavaScript does not have block scope, simple JavaScript scope is easy to understand. Another thing that easily confuses beginners is that JavaScript variables can be functionally parsed or declared in advance. There are many different names. What I’m talking about is one thing. Although JavaScript is interpreted and executed, it is not interpreted and executed step by step. Before it is actually interpreted and executed, the JavaScript interpreter will pre-parse the code and interpret the variable and function declarations in advance. This means We can call function before the function declaration statement. This is common to most people, but the and parsing of variables may look strange at first glance




Copy code
The code is as follows:


console.log(a); //undefined var a=3; console.log(a); //3 console .log(b); //Uncaught ReferenceError: b is not defined The declaration part of var a=3; in the above code has been pre-parsed before execution (but the assignment statement will not be executed) , so the first time it will be undefined without an error. After executing the assignment statement, you will get 3. Removing the last sentence of the above code will have the same effect as the following code.



Copy code

The code is as follows:

var a;
console.log(a); //undefined
a=3;
console.log(a); //3

However
If it were just like this, then the JavaScript scope problem would be very simple. However, the problems caused by function sub-functions make the scope more than simple. The big guy comes on stage - the execution environment or runtime context (good fellow): The execution context defines other data that variables or functions have access to, and determines their respective behaviors. Each execution environment has a variable object (VO) associated with it. All variables and functions defined in the execution environment will be stored in this object. The parser will access this internal object when processing data.

The global execution environment is the outermost execution environment. In the web browser, the global execution environment is the window object, so all global variables and functions are created as attributes and amplifications of the window object. Each function has its own execution environment. When the execution flow enters a function, the function environment will be pushed into a function stack. After the function is executed, the execution environment will be popped out of the stack and destroyed, and all the information stored in it will be pushed. The variable and function definitions are then destroyed, and control is returned to the previous execution environment. The global execution environment will not be destroyed until the application exits (the browser is closed).

Scope chain

When code is executed in an environment, a scope chain (sc) of variable objects will be created to ensure orderly access to variables and functions that the execution environment has access to. The first object in the scope is always the variable object (VO) of the environment where the code is currently executed

Copy code The code is as follows:

function a(x,y){
           var b=x y;
return b;
}


When function a is created, its scope chain is filled in the global object, which contains all global variables

image

If the execution environment is a function, then its activation object (AO) is used as the first object in the scope chain, the second object is the containing environment, and the next one is the containing environment of the containing environment. . . . .

Copy code The code is as follows:

function a(x,y){
           var b=x y;
return b;
}
var tatal=a(5,10);

At this time, the statement var total=a(5,10); The scope chain is as follows

image

During the running of the function, the resolution of identifiers is a process of searching level by level along the scope chain. Starting from the first object, going back step by step until an identifier with the same name is found. Once found, no more Continue to traverse and report an error if it cannot be found.

Let’s look at closures again

A previous blog once concluded: As long as there is the possibility of calling internal functions, JavaScript needs to retain the referenced functions. Moreover, the JavaScript runtime needs to track all variables that reference this internal function until the last variable is discarded before the JavaScript garbage collector can release the corresponding memory space. Looking back, it is easier to understand. The variables defined by the parent function are in the scope chain of the child function. If the child function is not destroyed, all variables and functions in its scope chain will be maintained and will not be destroyed.

Copy code The code is as follows:

for(var i=0;i elements[i].onclick=function(){
alert(i);
}
}

This is a classic mistake mentioned in the previous blog. Every time an element clicks alert, the alert is length. The scope chain of the click event handler bound to element in this code is like this

image

Due to the internal function (the click event handler may be called at any time), its scope chain cannot be destroyed (not to mention that in this example, i is in the global scope and can only be destroyed when the page is unloaded). The value of i The length value after the for loop is executed is always maintained, so length will be alerted every time onclick is triggered.

Copy code The code is as follows:

for(var i=0;i (function(n){
elements[n].onclick=function(){
alert(n);
}
})(i);
        }

Why does this work? At this time, the variable referenced by onclick becomes n, and due to the immediate execution of the function, each onclick function maintains the corresponding n (0~length-1) in the scope chain. , that’s it at this time.

Finally

In fact, after understanding the execution environment and scope chain, closure becomes obvious, but closure cannot be abused. As can be seen from the above example, closure will make the sub-function maintain its scope chain. All variables, functions and memory consume a lot of memory. Try to destroy variables that are no longer used by the parent function when using them.

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn