开发者

Help with Javascript scope

开发者 https://www.devze.com 2023-01-22 22:38 出处:网络
This example is a simplified version of my code. I\'m still trying to grasp the new way of writing javascript (as opposed to the way 10 years ago) so thanks for your patience. I need globalVal\'s valu

This example is a simplified version of my code. I'm still trying to grasp the new way of writing javascript (as opposed to the way 10 years ago) so thanks for your patience. I need globalVal's value to be accessible and I'm having trouble. The value is obtained from a function that is called as an argument from another method. The example is probably easier to see. Just need to be able to have access to globalvar from everywhere in the DOM. Is this possible? Thanks

<html>
<head>
<script type="text/javascript">开发者_开发技巧
    var globalvar;

    function initialize() { 
        var someVariable = 5;
        doSomething(someVariable, getTheVar);
    }

    function doSomething(someVariable, expectGlobalVar) {
        //alert(someVariable);
        alert(expectGlobalVar);
    }

    function getTheVar() {
        globalVar = "test"; 
        return globalVar;

    }
</script>
<title></title>
</head>
<body onload="initialize()">
    This is a test
</body>
</html>


You're mostly fine, you can directly access globalVar from any script running anywhere in the page if you declare it the way you have.

Specifically: Using var x; at page-level scope (that is, outside of any function) declares a property on the window object (it has a special feature in that it can't be deleted, but that's not important here).

var foo = 2;
window.foo = 2; // Basically the same other than the delete thing we're not worrying about here

And so:

var foo = 2;
alert(foo);        // alerts "2"
alert(window.foo); // also alerts "2"
window.bar = 4;
alert(window.bar); // alerts "4"
alert(bar);        // also alerts "4"

Naturally this is only true at the top level, outside of any functions. Inside functions, you're declaring something local to the function. (In essence; it's actually a lot more interesting than that.)

But since you've asked about scope, it's worth nothing that all of the other things you've defined (initialize, getTheVar, doSomething) are also globals. In general, you want to avoid putting anything in the global namespace that you can avoid putting there.

For that reason, I advocate always using a "scoping function":

(function() {
    // your code here
})();

...and explicitly exporting exactly and only the things you really need to be global (by assigning them to properties on window).

In your case, you've said you need globalVar and you've also used initialize (although there are other ways to do what you're doing in initialize), so you could do this:

(function() {
    var globalvar;

    // Exports
    window.globalVar = globalVar;
    window.initialize = initialize;

    // Implementation

    function initialize() { 
        var someVariable = 5;
        doSomething(someVariable, getTheVar);
    }

    function doSomething(someVariable, expectGlobalVar) {
        //alert(someVariable);
        alert(expectGlobalVar);
    }

    function getTheVar() {
        globalVar = "test"; 
        return globalVar;
    }
})();

But you can take it further. Since you're not calling initialize until the load event of the body element, you could avoid publishing initialize. Just put your script tag at the end of the document, just before the closing </body> tag (as the YUI folks recommend), and do your initialization there:

<html>
<head>
<title>...</title>
</head>
<body>This is a test
<script type='text/javascript'>
(function() {
    var globalvar;

    // Initialization
    initialize();

    // Exports
    window.globalVar = globalVar;

    // Implementation
    function initialize() { 
        var someVariable = 5;
        doSomething(someVariable, getTheVar);
    }

    function doSomething(someVariable, expectGlobalVar) {
        //alert(someVariable);
        alert(expectGlobalVar);
    }

    function getTheVar() {
        globalVar = "test"; 
        return globalVar;
    }
})();
</script>
</body>
</html>

The DOM is fully loaded and ready to go at that point.

But we can go even further if we want: We can have nothing in the global namespace if we like. If you hook up all of your handlers within your initialize function rather than using onload, onclick, and similar attributes, there's no need for globalVar to be global except to your code. (You hook up handlers after the fact by using attachEvent [on IE], addEventListener [on standards-based browsers], or better yet using a library like jQuery, Closure, Prototype, YUI, or any of several others.)


You should call function getTheVar instead of passing it:

function initialize() { 
        var someVariable = 5;
        doSomething(someVariable, getTheVar());
}


You're doing it right.

Any variable which is declared in global scope, just like you have in the example, will be available from every scope in the window.

(BTW, declaring a global var is [almost] equivalent to window.myVar = someValue;)

The problem in your example is that you are not actually calling getTheVar on the fourth line, but rather just passing the function itself. You probably want this:

doSomething(someVariable, getTheVar());
0

精彩评论

暂无评论...
验证码 换一张
取 消