In some C-like programming languages, each piece of code within the curly braces has its own scope, and the variables are not visible outside the code snippet that declares them (i.e. we cannot directly access the variables declared within the code snippet outside the code snippet), which we call block-level scopes, however, unlike this type of programming language, JavaScript is not a block-level scope. Instead, JavaScript uses block-level scopes: variables are defined in the body of the function in which they are declared and in any function within which the body of the function is nested.
In the code shown below, variables I, j, and K are defined in different locations, all within the same scope-the three variables are defined within the function body.
function Text(o) {vari = 0;//I am defined by the entire function body if(typeofo = = "Object"){ varj = 0;//j is defined in the function body, not just within this code snippet for(vark = 0; K < 10; k++) {//k is defined in the function body, not just in the circulation bodyConsole.log (k);//output numbers 0 to 9 }; Console.log (k); // k already defined, output} console.log (j); //J has been defined, but may not be initialized}
The function scope of JavaScript is that all variables declared within a function are always visible inside the function body. Interestingly, this means that the variable is even available before the declaration. This feature of JavaScript is informally called declaration in advance, i.e. all variables declared in the JavaScript function (but not related to assignment) are "advanced" to the top of the function body, and look at the following code:
1 function f () {2 console.log (scope); // output "undefined" instead of "global" 3 var scope = "local"; // The variable assigns the initial value here, but the variable itself is defined everywhere in the function body 4 Console.log (scope); // output "local" 5 }
You might mistakenly assume that the first row in the function outputs "global" because the code has not yet executed the local variable declared to the VAR statement. In fact, because of the function scope, the local function is always defined in the whole function body, that is, the function body local variable obscures the full name global variable. However, local variables are truly assigned only when the program executes to the VAR statement. Therefore, the above procedure is equivalent to: Declare the variable inside the function "ahead" to the top of the function body, while the variable initialization remains in its original position:
1 function f () {2 var scope; // local variables declared at the top of the function 3 Console.log (scope); // variable exists, but its value is "undefined" 4 Scope = "local"; // here it initializes and assigns a value 5 Console.log (scope); // here it has the value we expect . 6 }
Next, talk about the concept of the scope chain of JavaScript. In the JavaScript Rhino book, there is a small section on the definition and introduction of scope chains.
JavaScript is a lexical-scoped language: You can know the scope of a variable by reading several lines of source code that contain variable definitions. Global variables are always defined in a program. A local variable is always defined within the body of the function in which it is declared and inside the function in which it is nested.
If you consider a local variable as a property of a custom implemented object, you can interpret the scope of the variable in a different perspective. Each segment of the Javascripe Code (Global Code or function) has a scope chain associated with it. This scope chain is a list of objects or linked lists that define the variables in the scope of this code. When JavaScript needs to look up the value of the variable x (the process is called "Variable resolution"), it is searched from the first object in the chain, and if the object has a property called X, the value of the property is used directly, and if the property named X does not exist in the first object, JavaScript continues to find the next object on the chain. If the second object still does not have a property named X, it will continue to look for the next object, and so on, if none of the objects on the scope chain contains attribute x, then it is assumed that there is no X on the scope chain of the code and eventually throws a reference error exception.
In the topmost code of JavaScript (that is, code that does not contain any function definitions), the scope chain consists of a global object. In the body without nested functions, there are two objects on the scope chain, the first is the object that defines the function arguments and local variables, and the second is the global object. Within a nested function body, there are at least three objects on the scope chain. It is important to understand the creation rules of the object chain. When a function is defined, it actually holds a scope chain. When this function is called, it creates a new object to store its local variables, adds the object to the saved scope chain, and creates a new "chain" that represents the scope of the function call. For nested functions, things become more interesting, and each time an external function is called, the inner function is redefined again. Because each time an external function is called, the scope chain is different. External functions are subtly different every time they are defined--each time an external function is called, the code for the intrinsic function is the same, and the scope chain of the associated code is not the same.
This definition and introduction may be difficult to understand, so let's look at a piece of code first:
1Name= "Lwy";//a global variable is defined in the global scope name, with a value of Lwy2 functionT () {3 varName= "Tlwy";//defines a local variable name in the scope of the function T, with a value of Tlwy4 functions () {5 varName= "Slwy";//The function T in the scope of the inline function s defines a local variable name with a value of Slwy6Console.log (name);//Output Name7 }8 functionSS () {9Console.log (name);//Output NameTen } OneS ();//Call execution function s ASS ();//Call execution function SS - } -T ();//Call execution function T
When you execute S, the execution environment (the calling object) of the function S is created, the object is placed at the beginning of the list, and then the calling object of the function T is linked after, and finally, the global object.
The scope chain is: s ()->t ()->window (function s and function t and Object window can find the variable name)
Then looking for the variable name from the beginning of the list, it is obvious that name is "Slwy".
But when the SS () is executed, the scope chain is: SS ()->t ()->window (except for the function SS, the function T and the object window can find the variable name), so name is "Tlwy"
So, let's take a look at an interesting example:
1 <HTML>2 <Head>3 <Scripttype= "Text/javascript">4 functionButtoninit () {5 for(varI=1; I<4; I++){6 varb=document.getElementById ("Button"+i);7 B.addeventlistener ("Click",function() {alert ("Button"+i);},false);8 }9 }Ten window.onload=Buttoninit; One </Script> A </Head> - <Body> - <ButtonID= "Button1">Button1</Button> the <ButtonID= "Button2">Button2</Button> - <ButtonID= "Button3">Button3</Button> - </Body> - </HTML>
After the document is loaded, click events are registered to several buttons. When we click on the button, you will feel that each button click will pop up the corresponding content within the button.
However incorrect, three buttons will eventually pop up: "Button4".
Cause: When the registration event ends, I has a value of 4, and when the button is clicked, the event function is functions () {Alert ("button" +i);} This anonymous function does not have I, according to the scope chain (anonymous function-- buttoninit->window), so in the Buttoninit function to find, at this time I at the end of the loop value is 4, so, Whichever button you click will pop up "Button4".
JavaScript Chapter-----Function scope, function scope chain and declaration in advance