JavaScript中變數範圍問題

來源:互聯網
上載者:User

摘錄一篇:JavaScript中變數的範圍問題

 

The scope of a variable is all parts of a program where it is visible. Being visible means that the variable has been declared and is available for use. A variable that is visible everywhere in the program has global scope. A variable that is visible only in a specific context—a function, for example—has local scope. A context is the set of defined data that make up the execution environment. When the browser starts, it creates the global context in which JavaScript will execute. This context contains the definitions of the features of the JavaScript language (the Array and Math objects, for example) in addition to browser-specific objects like Navigator.

Note 

If you’re a JavaScript beginner, you may wish to only skim the next few sections on scope, and come back to them when you’re more comfortable with the language.

Variable Scope and Functions

When a function is invoked, the interpreter creates a new local context for the duration of its execution. All variables declared in the function (including its arguments) exist only within this context. When the function returns, the context is destroyed. So, if you wish to preserve a value across multiple function calls, you might need to declare a global variable.

Note 

JavaScript lacks static variables like C—you would have to use global variables to achieve this effect.

When a variable is referenced in a function, the interpreter first checks the local context for a variable of that name. If the variable has not been declared in the local context, the interpreter checks the enclosing context. If it is not found in the enclosing context, the interpreter repeats the process recursively until either the variable is found or the global context is reached.

It is important to note that the contexts are checked with respect to the source code and not the current call tree. This type of scoping is called static scoping (or lexical scoping). In this way, locally declared variables can hide variables of the same name that are declared in an enclosing context. The following example illustrates variable hiding:

var scope = "global";function myFunction() { var scope = "local"; document.writeln("The value of scope in myFunction is: " + scope);}myFunction();document.writeln("The value of scope in the global context is: " + scope);

The result is shown in Figure 3-2. The local variable scope has hidden the value of the global variable named scope. Note that omitting var from the first line of myFunction would assign the value "local" to the global variable scope.


Figure 3-2: A local variable hides a global variable of the same name.

There are some important subtleties regarding variable scope. The first is that each browser window has its own global context. So it is unclear at first glance how to access and manipulate data in other browser windows. Fortunately, JavaScript enables you to do so by providing access to frames and other named windows. The mechanics of cross-window interaction is covered in later chapters, particularly Chapter 12.

The second subtlety related to scoping is that, no matter where a variable is declared in a context, it is visible throughout that context. This implies that a variable declared at the end of a function is visible throughout the whole function. However, any initialization that is included in the declaration is only performed when that line of code is reached. The result is that it is possible to access a variable before it is initialized, as in the following example:

function myFunction() { document.writeln("The value of x before initialization in myFunction is: ", x); var x = "Hullo there!"; document.writeln("The value of x after initialization in myFunction is: ", x);} myFunction();

The result is shown in Figure 3-3. Note how scope has undefined value before it is initialized.


Figure 3-3: Variables may be visible without yet being initialized.

The third subtlety has to do with static scoping. Consider the following code,

var scope = "global";function outerFunction(){   var scope = "local";   innerFunction();}function innerFunction(){   alert("The value of scope is: " + scope);}outerFunction();

which results in:

This example illustrates a critical aspect of static scoping: the value of scope seen in innerFunction is the value present in enclosing the global context: "global." It does not see the value set in outerFunction. That value of scope is local to that function and not visible outside of it. The correct value for scope was found by examination of the enclosing context in the original JavaScript source code. The interpreter can infer the correct value by “static” examination of the program text. Hence the name “static scoping.”

Variable Scope and Event Handlers

We saw that variables declared inside functions are local to that function. The same rule applies to JavaScript included in event handlers: the text of the event handler is its own context. The following script illustrates this fact. It declares a global variable x as well as a variable x within an event handler:

<<script type="text/javascript">>  var x = "global";<</script>><<form action="#" method="get">><<input type="button" value="Mouse over me first"   onmouseover="var x = 'local'; alert('Inside this event hander x is ' + x);" />><<input type="button" value="Mouse over me next! "   onmouseover="alert('Inside this event hander x is ' + x);" />><</form>>

Move the mouse over the first button to see that the value of x in that context has been set to "local". You can see that that x is not the same as the global x by then moving the mouse over the second button. The value printed by the second button is "global", indicating that the x set in the first handler was not the global variable of the same name.

Remember that because JavaScript is statically scoped, it’s only variables declared within the text of an event handler that have their own context. Consider this example:

<<script type="text/javascript">>var x = "global";function printx(){  alert("Inside this function x is " + x);}<</script>><<form action="#" method="get">><<input type="button" value="Mouse over me!"   onmouseover="var x = 'local'; printx();" />><</form>>

You can see that the value of x that is printed is "global". Static scoping at work again: Since the context of the function printx is global, it doesn’t see the local value set in the event handler text.

Execution Contexts

The preceding discussion of how variable names are resolved hints at the fact that execution contexts vary dynamically and reside within one another. For example, if a variable referenced in the text of an event handler cannot be found within that event handler’s context, the interpreter “widens” its view by looking for a global variable of the same name. You can think of the event handler’s local context as residing within the global context. If a name can’t be resolved locally, the enclosing (global) scope is checked.

In fact, this is exactly the right way to think about execution contexts in JavaScript. An (X)HTML document can be thought of as a series of embedded contexts: an all-enclosing JavaScript global scope within which resides a browser context, within which resides the current window. Inside the window resides a document, within which might be a form containing a button. If script executing in the context of the button references a variable not known in the button’s context, the interpreter would first search the form’s context, then the document’s, then the window’s, the browser’s, and eventually the global context.

The exact details of how this works comprise JavaScript’s object model, a subject discussed in later chapters. A comprehensive knowledge of the topic is not really required to program in JavaScript, but helps tremendously in understanding where the objects available to your scripts come from, and how they are related. It will also go a long way in setting you apart from the typical JavaScript developer!

 

錄自:《JavaScript 2.0-The Complete Reference》Thomas Powell ,Fritz Schneider, second edition,

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.