JavaScript变量的范围

时间:2009-10-21 03:17:20

标签: javascript

是否可以在同一个.html页面上定义函数之上的一些全局变量?

    <script type="text/javascript">

        birthYear = document.getElementById('<%=ddlBirthYear.ClientID %>');
        birthMonth = document.getElementById('<%=ddlBirthMonth.ClientID %>');
        birthDay = document.getElementById('<%=ddlBirthYear.ClientID %>');

        function ValidateCardField(validator, args)
        {
            if (args.Value.length > 0)
                args.IsValid = true;
            else
                args.IsValid = false;
        }
...

我得到变量值的空值。

8 个答案:

答案 0 :(得分:3)

是的,可以使用全局变量,并且您似乎正确地执行了此操作(尽管您应该使用var关键字来定义它们)。您目前面临的问题是您在渲染之前尝试访问DOM中的元素。您需要做的是全局定义变量,然后在将页面分配给适当的DOM元素之前等待页面加载......

var birthYear, birthMonth, birthDay;

window.onload = function() {
  birthYear = document.getElementById('<%=ddlBirthYear.ClientID %>');
  birthMonth = document.getElementById('<%=ddlBirthMonth.ClientID %>');
  birthDay = document.getElementById('<%=ddlBirthYear.ClientID %>');
}

现在,在页面加载后,变量将可全局访问。

答案 1 :(得分:2)

您的问题可能是在DOM完全初始化之前正在执行脚本。所以当这些代码行运行时:

    birthYear = document.getElementById('<%=ddlBirthYear.ClientID %>');
    birthMonth = document.getElementById('<%=ddlBirthMonth.ClientID %>');
    birthDay = document.getElementById('<%=ddlBirthYear.ClientID %>');

就浏览器而言,尚未存在具有这些ID的元素。解决这个问题的一种方法是将变量声明为null,然后在您在页面(客户端!)加载处理程序中调用的函数中初始化它们。

可能还值得检查(通过在浏览器中查看源代码),那些ClientID值是您认为的值,并且具有这些ID的元素确实存在于呈现的HTML中。

答案 2 :(得分:1)

是的,可以声明全局变量,但它们与函数定义在同一名称空间内,如果变量未在函数体中定义并在内部访问,则它们向下下降并到达全局/外部范围变量并使用那些。

OP - 您应该尝试将<script>块移到最终正文标记之前,或者采用domready / onload函数。

答案 3 :(得分:1)

Javascript中的var关键字意味着那些变量全局(全局不幸的是默认值)但功能范围 - 在使用var之外没有多大意义任何功能的范围(并且可能令人困惑),尽管它是合法的。但var和函数范围的美妙之处在于允许您定义丰富的闭包,这是Javascript真正美丽的方面之一 - 即,如果您在一些外部函数中定义了示例代码,并且outerfunction返回{{ 1}}或一个将后者作为其值之一的对象,内部函数将访问其外部函数中定义的非全局变量,而世界其他地方则被屏蔽掉 - 这是一种更好的方法使用ValidateCardField作为关键字的Java / C ++方法来做“私有字段”......!

答案 4 :(得分:1)

修改

我明白了问题所在。当你在全局上下文中调用那些时,DOM没有完全加载(当它从函数调用时,DOM已经加载了)。

在这种情况下,您可能最好使用jQuery或Prototype等框架。

在jQuery中加载DOM后运行代码,http://docs.jquery.com/Events/ready,原型<{3}}

e.g。 在jQuery中:

 $(document).ready(function () {
    birthYear = document.getElementById('<%=ddlBirthYear.ClientID %>');
    birthMonth = document.getElementById('<%=ddlBirthMonth.ClientID %>');
    birthDay = document.getElementById('<%=ddlBirthYear.ClientID %>');
 });

并在原型中:

 document.observe("dom:loaded", function() {
    birthYear = document.getElementById('<%=ddlBirthYear.ClientID %>');
    birthMonth = document.getElementById('<%=ddlBirthMonth.ClientID %>');
    birthDay = document.getElementById('<%=ddlBirthYear.ClientID %>');
 });

答案 5 :(得分:1)

问题不是范围界定,而是执行顺序之一。在原始实现中,在触发函数之前不会检索DOM元素。现在,只要解析JavaScript就会查找元素,这可能是在文档(因此,元素)被加载之前 - 因此在调用函数时它们是null

答案 6 :(得分:0)

如果您对此类事情不确定,可以编写快速测试程序并进行测试。

<html><head>
<script type="text/javascript">
var x = document.getElementById("bob");

function helloWorld(){
    alert(x == null);
}
</script>
</head>
<body onload="javascript:helloWorld();">
<div id="bob">hello back!</div>
</body>
</html>

答案 7 :(得分:0)

我认为问题与变量的范围无关,而是在尝试为它们分配对某些页面元素的引用时。可能在加载所有页面元素之前脚本正在运行。因此,当尝试查找不存在的元素时,getElementById函数将失败。 将脚本包装在window对象的onLoad事件中,如下所示:

window.onload = function () (
     // Your code here ...
);