帮助Javascript范围

时间:2010-10-30 14:04:01

标签: javascript scope

此示例是我的代码的简化版本。我仍在努力掌握编写javascript的新方法(与10年前的方式相反),感谢您的耐心等待。我需要globalVal的值才能访问,我遇到了麻烦。该值是从另一个方法中作为参数调用的函数获得的。这个例子可能更容易看到。只需要能够从DOM中的任何位置访问globalvar。这可能吗?感谢

<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>

3 个答案:

答案 0 :(得分:1)

你很好,你可以从你在网页中任何地方运行的任何脚本直接访问globalVar

具体来说:在页面级范围内使用var x;(即在任何函数之外)在window对象上声明一个属性(它具有一个特殊功能,因为它无法删除,但这在这里并不重要。)

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

所以:

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"

当然,除了任何功能之外,这只适用于顶层。在 Inside 函数中,您将声明函数的本地内容。 (从本质上讲,它实际上比那更有趣。)

但是既然你已经询问了范围,那么你定义的所有其他内容(initializegetTheVardoSomething也< / em>全局。通常,您希望避免在全局命名空间中放置任何可以避免放在那里的内容。

出于这个原因,我主张总是使用“范围函数”:

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

...并且明确地导出您确实需要全局的内容(通过将它们分配给window上的属性)。

在你的情况下,你说你需要globalVar并且你还使用了initialize(尽管还有其他方法可以做你在initialize中所做的事情),所以你可以这样做:

(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;
    }
})();

但你可以更进一步。由于您在initialize元素的load事件之前未调用body,因此您可以避免发布initialize。只需将您的脚本标记放在文档的 end ,就在结束</body>标记之前(如the YUI folks推荐的那样),然后在那里进行初始化:

<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>

此时DOM为fully loaded and ready to go

但如果我们愿意,我们可以进一步 :如果我们愿意,我们可以在全局命名空间中拥有 nothing 。如果您在initialize函数中挂钩所有处理程序而不是使用onloadonclick和类似属性,则globalVar除了<{1}}之外不需要全局你的代码。 (事后通过使用attachEvent [在IE上],addEventListener [在基于标准的浏览器上],或者更好地使用像jQuery,{{3}这样的库,来处理事件处理程序},ClosurePrototypeYUI。)

答案 1 :(得分:0)

你做对了

在全局范围内声明的任何变量,就像在示例中一样,将在窗口中的每个范围内可用。

(顺便说一句,声明全局变量[几乎]相当于window.myVar = someValue;

你的例子中的问题是你实际上并没有在第四行调用getTheVar,而只是传递函数本身。你可能想要这个:

doSomething(someVariable, getTheVar());

答案 2 :(得分:0)

你应该调用函数getTheVar而不是传递它:

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