Objects that can be accessed anywhere in the code have global scope, typically with global scope in the following situations:
(1) The outermost function and the variables defined outside the outermost function have global scope, for example:
(2) All variables that are directly assigned to the last definition are automatically declared to have global scope, for example:
The variable blogname has a global scope, and AuthorName cannot be accessed outside the function.
(3) All Window object properties have global scope
In general, the built-in properties of the Window object have global scope, such as Window.name, Window.location, Window.top, and so on.1 scope (local scope)
In contrast to the global scope, local scopes are generally accessible only within a fixed code fragment, the most common of which is inside the function, and in some places it is also seen that this scope is called a function scope, such as the Blogname in the following code and the function Innersay only have local scope.
When a function is created, its scope chain is populated with data objects that can be accessed by creating the scope of this function. For example, define a function such as the following:
When the function add is created, it fills a global object in its scope chain, which contains all the global variables, as shown (note: The picture shows only a subset of all variables):
The scope of the function add will be used at execution time. For example, execute the following code:
Executing this function creates an internal object called the runtime context (execution context), which defines the environment at which the function executes. Each run-time context has its own scope chain, which is used for identifier resolution, when the runtime context is created, and its scope chain is initialized to the object contained by [[Scope]] of the currently running function.
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 the "Activation Object", which contains all the local variables, named arguments, parameter sets, and this of the function, which is then pushed into the front of the scope chain, and the active object is destroyed when the run-time context is destroyed. The new scope chain is as follows:
During the execution of a function, no variable is encountered, and an identifier parsing process is passed to determine where to get and store the data. The process from the scope chain head, that is, starting from the active object search, find an identifier of the same name, if found to use this identifier corresponding to the variable, if not found to continue to search the scope chain of the next object, if the search all objects are not found, the identifier is considered undefined. Each identifier undergoes such a search process during the execution of the function.Scope Chain and code optimization
From the structure of the scope chain, you can see that in the scope chain of the run-time context, the deeper the identifier is, the slower the read and write speed. As shown, because global variables always exist at the end of the run-time context chain, finding global variables is the slowest when identifiers are resolved. Therefore, when writing code, you should use as few global variables as possible, using local variables as much as you can. A good rule of thumb is that if a cross-scope object is referenced more than once, it is stored in a local variable before it is used. For example, the following code:
This function refers to the two global variable document and finds that the variable must traverse the entire scope chain until it is finally found in the global object. This code can be rewritten as follows:
This code is simple and will not show a huge performance boost after rewriting, but if there are a large number of global variables in the program that are accessed from time to time, the rewritten code performance can be significantly improved.Change the scope chain
The runtime context is unique for each execution of the function, so calling the same function multiple times will result in multiple runtime contexts being created and the execution context destroyed when the function finishes executing. Each run-time context is associated with a scope chain. In general, the scope chain is only affected by the WITH statement and catch statement during the run-time context.
The WITH statement is a quick way to apply an object to avoid writing duplicate code. For example:
Using the width statement here to avoid writing the document multiple times seems more efficient and actually creates performance problems.
When the code runs to the WITH statement, the scope chain of the run-time 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 into 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 cost is higher. As shown in the following:
Therefore, you should avoid using the WITH statement in your program, in which case you can improve performance by simply storing the document in a local variable.
The other one that changes the scope chain is the catch statement in the Try-catch statement. When an error occurs in a try code block, the execution jumps to the catch statement, and then pushes the exception object into a Mutable object and puts it in the scope's head. Inside a catch code block, all local variables of the function are placed in the second scope chain object. Example code:
Note that once the Catch statement finishes executing, the scope chain opportunity returns to the previous state. Try-catch statements are useful in code debugging and exception handling, so it is not recommended to avoid them altogether. You can reduce the performance impact of catch statements by optimizing your code. A good pattern is to delegate the error to a function handler, for example:
After the optimized code, the HandleError method is the only code executed in the Catch clause. The function receives the exception object as a parameter, so you can handle the error more flexibly and uniformly. Because only one statement is executed and there is no access to local variables, temporary changes to the scope chain do not affect code performance.