JavaScript scope and scope chain for a simple introduction

Source: Internet
Author: User
Tags exception handling
JavaScript scopes
Any programming language has the concept of scope, in short, the scope is the accessibility of variables and functions, that is, the scope controls the visibility and life cycle of variables and functions. In JavaScript, the scope of a variable has two kinds, global scope and local scope.
1. Global scope
Objects that can be accessed anywhere in your code have global scope, and in general there are several scenarios that have global scope:
(1) The outermost function and variables defined outside the outermost function have global scope, for example:
View Sourceprint?
01 varauthorName="山边小溪";
02 functiondoSomething(){
03     varblogName="梦想天空";
04     functioninnerSay(){
05         alert(blogName);
06     }
07     innerSay();
08 }
09 alert(authorName); //山边小溪
10 alert(blogName); //脚本错误
11 doSomething(); //梦想天空
12 innerSay() //脚本错误
(2) All variables that are directly assigned at the end of the definition are automatically declared to have global scope, for example:
View Sourceprint?
1 functiondoSomething(){
2     varauthorName="山边小溪";
3     blogName="梦想天空";
4     alert(authorName);
5 }
6 alert(blogName); //梦想天空
7 alert(authorName); //脚本错误
The variable blogname has a global scope and authorname cannot be accessed outside of the function.
(3) Properties of all window objects have global scope
Typically, the built-in properties of a Window object have global scope, such as Window.name, Window.location, Window.top, and so on.
1. Local scope (global scope)
As opposed to global scopes, a local scope is generally accessible only within a fixed code fragment, most commonly such as within a function, and in some places it is seen as being scoped to a function, for example, Blogname and function Innersay in the following code have only local scopes.
View Sourceprint?
1 functiondoSomething(){
2     varblogName="梦想天空";
3     functioninnerSay(){
4         alert(blogName);
5     }
6     innerSay();
7 }
8 alert(blogName); //脚本错误
9 innerSay(); //脚本错误
Scope chain (Scope Chain)
In JavaScript, a function is also an object, in fact, everything in JavaScript is an object. function objects, like other objects, have properties that can be accessed through code and a series of internal properties that are accessible only to the JavaScript engine. One of the internal properties is [[Scope]], defined by the third edition of the ECMA-262 Standard, which contains a collection of objects in the scope of the function being created, which is called the scope chain of the function, which determines which data can be accessed by the function.
When a function is created, its scope chain is populated with data objects that are accessible in the scope of this function creation. For example, define a function such as the following:
View Sourceprint?
1 functionadd(num1,num2) {
2     varsum = num1 + num2;
3     returnsum;
4 }
When the function add is created, its scope chain fills in a global object that contains all the global variables, as shown in the following illustration (note: The picture illustrates only a subset of the variables):

The scope of the function add will be used at execution time. For example, execute the following code:
View Sourceprint?
1 vartotal = add(5,10);
When this function is executed, an internal object called the Run-time context (execution contexts) is created, and the runtime context defines the environment at which the function executes. Each run-time context has its own scope chain, used for identifier resolution, when the runtime context is created, and its scope chain is initialized to the object contained in the current running function's [[Scope]].
These values are copied into the scope chain of the run-time context in the order in which they appear in the function. Together they form a new object, called active object (Activation object), which contains all the local variables of the function, named arguments, a collection of parameters, and this, and then this object is pushed into the front of the scope chain, and the active object is destroyed when the runtime context is destroyed. The new scope chain is shown in the following illustration:

During function execution, a variable is not encountered, and it undergoes an identifier resolution process to determine where to get and store the data. The process from the scope chain head, that is, from the active object search, look for an identifier with the same name, if found to use the variable corresponding to this identifier, if you do not find the next object in the scope chain continues to search, if all objects are not found, the identifier is not defined. During function execution, each identifier undergoes such a search process.
Scope Chain and code optimization
It can be seen from the structure of the scope chain that the deeper the identifier is in the scope chain of the runtime context, the slower the read and write speed will be. As shown in the figure above, because global variables always exist at the very end of the run-time context-scoped chain, finding global variables is the slowest when identifiers are parsed. So, when writing code, you should use as little global variables as possible, and use local variables whenever you can. A good rule of thumb is that if a cross scoped object is referenced more than once, it is stored in a local variable for reuse. For example, the following code:
View Sourceprint?
1 functionchangeColor(){
2     document.getElementById("btnChange").onclick=function(){
3         document.getElementById("targetCanvas").style.backgroundColor="red";
4     };
5 }
This function refers to a two-time global variable document, which must traverse the entire scope chain until it is finally found in the global object. This code can be rewritten as follows:
View Sourceprint?
1 functionchangeColor(){
2     vardoc=document;
3     doc.getElementById("btnChange").onclick=function(){
4         doc.getElementById("targetCanvas").style.backgroundColor="red";
5     };
6 }
This code is simpler and will not show a significant performance boost when overridden, but if a large number of global variables are accessed from time to time in the program, the rewritten code performance can improve significantly.
Changing the scope chain
The run-time context of a function is unique each time it executes, so calling the same function multiple times will result in the creation of multiple run-time contexts, and the execution context will be destroyed when the function completes. Each run-time context is associated with a scope chain. In general, the scope chain is only affected by the WITH statement and catch statements during runtime contexts.
The WITH statement is a quick way to use an object to avoid writing duplicate code. For example:
View Sourceprint?
01 functioninitUI(){
02     with(document){
03         varbd=body,
04             links=getElementsByTagName("a"),
05             i=0,
06             len=links.length;
07         while(i < len){
08             update(links[i++]);
09         }
10         getElementById("btnInit").onclick=function(){
11             doSomething();
12         };
13     }
14 }
Using the width statement to avoid writing the document multiple times, it looks more efficient and actually creates a performance problem.
When the code runs to the WITH statement, the scope chain of the runtime context is temporarily changed. A new Mutable object is created that contains all the properties of the object specified by the parameter. This object will be pushed to the head of the scope chain, which means that all local variables of the function are now in the second scope chain object, so the access costs are higher. As shown in the following illustration:

Therefore, you should avoid using the WITH statement in your program, in this case, simply storing the document in a local variable can improve performance.
Another change in the scope chain is the catch statement in the Try-catch statement. When an error occurs in the try block, the execution jumps to the catch statement, and then pushes the exception object into a Mutable object and places the header on the scope. Inside a catch code block, all local variables of a function are placed in the second scope chain object. Sample code:
View Sourceprint?
1 try{
2     doSomething();
3 }catch(ex){
4     alert(ex.message); //作用域链在此处改变
5 }
Note that once the Catch statement has finished executing, the scope chain opportunity returns to the previous state. Try-catch statements are useful in code debugging and exception handling and are therefore not recommended for total avoidance. You can optimize your code to reduce the impact of catch statements on performance. A good pattern is to delegate the error to a function, for example:
View Sourceprint?
1 try{
2     doSomething();
3 }catch(ex){
4     handleError(ex); //委托给处理器方法
5 }
Optimized code, the HandleError method is the only code that executes in a catch clause. The function receives the exception object as an argument so you can be more flexible and unified in handling errors. Because only one statement is executed and no local variables are accessed, the temporary change in the scope chain does not affect code performance.
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.