【问题标题】:Is there any purpose to redeclaring JavaScript variables?重新声明 JavaScript 变量有什么目的吗?
【发布时间】:2010-12-24 06:07:54
【问题描述】:

我是 JavaScript 新手。

<html>
<body>
<script type="text/javascript">
var x=5;
document.write(x);
document.write("<br />");
var x;
document.write(x);
</script>
</body>
</html>

结果是:

5
5

x 第二次被声明时,它应该是未定义的,但它保持之前的值。请说明这个重新声明是否有任何特殊目的。

【问题讨论】:

  • 你问题的内容是关于一个具体的例子,下面已经很好地回答了。但是,我发现this answer 对类似问题的回答很好地回答了问题标题中的一般情况(何时/为什么要重新声明 JavaScript 变量?)。

标签: javascript variables redeclaration


【解决方案1】:

您并没有真正重新声明变量。

JavaScript 中的变量语句会被提升,这意味着它们在 解析时 被评估,然后在 运行时 进行分配。

您的代码在解析阶段结束,执行之前看起来像这样:

var x;
x = 5;

document.write(x);
document.write("<br />");
document.write(x);

【讨论】:

    【解决方案2】:

    var 单独不执行分配。它仅表明当您在出现 var 的整个范围内使用变量名称时,您谈论的是局部变量而不是全局变量(有争议的默认值)。 var 在函数被解析并在整个范围内保持时被发现,所以你把它放在哪里是无关紧要的:

    var a= 0;
    
    function foo() {
        a= 1;
        return a;
        var a;
    }
    
    var b= foo();
    alert('global a='+a+', local a='+b);
    

    导致global a= 0, local a= 1:即使var 语句在foo() 的执行过程中从未到达,它仍然有效地将a 设为局部变量。

    所以在同一范围内第二次声明var x 是完全多余的。但是,有时您可能仍会这样做,通常是当您在同一函数中重新使用局部变量名称以进行第二次独立使用时。最常见的:

    for (var i= 0; i<onething.length; i++) {
        ...do some trivial loop...
    }
    
    for (var i= 0; i<anotherthing.length; i++) {
        ...do another trivial loop...
    }
    

    虽然您当然可以省略第二个 var,并且像 jslint 这样的工具会要求您这样做,但这实际上可能不是一个好主意。

    假设您稍后更改或删除第一个循环,使其不再将i 声明为var。现在剩下的第二个循环突然将含义从局部变量更改为全局变量。如果您在更新第一个循环时没有注意到第二个循环对其具有隐藏的依赖项(并且您很可能没有注意到鉴于眼睛如何将模式for(...=0 ; ...&lt;...; ...++) 忽略为“哦,这只是一个标准迭代器” ),您遇到了一个微妙且令人讨厌的调试问题。

    【讨论】:

      【解决方案3】:

      所以当它第二次声明的 x 应该是未定义的时候

      规范的哪一部分是这样说的?

      “未定义的行为”并不意味着“变量将是undefined”。

      【讨论】:

        【解决方案4】:

        第二个 var x 完全是多余的。

        【讨论】:

          【解决方案5】:

          同一范围内,完全没有必要“重新声明”一个变量。

          【讨论】:

            【解决方案6】:

            就我对 javascript 的理解而言,var 关键字的使用在全局范围内是完全可选的。对于函数来说,情况就不同了。

            在函数内部时,使用var 关键字表示该变量是函数的局部变量(而不是默认全局变量)。

            我个人在全局范围内使用var 来表明第一次声明和/或使用变量。

            您可以参考http://www.w3schools.com/js/js_variables.asp了解更多信息。

            【讨论】:

            • 不,不是:如果不指定var,变量将属于全局范围。
            • var 用于函数内的作用域,如果你不使用 var 在函数内它是自动全局的。
            • 嘿——都在同一个 20 秒内。
            • @Kenaniah:你应该删除你的答案,否则你很快就会面临一堆反对票的风险......
            • 我很抱歉。我忘了提到它在函数中的用法来指示局部变量(相对于全局变量)。虽然这个问题涉及全球范围,但我应该包括在内。帖子已编辑;-)
            【解决方案7】:

            另外,程序员可能想使用var 来本地化一个变量:

            <script>
            var x= 'this is global x';
            function my_x() {
             var x= 'localized x';
             alert(x);
            }
            my_x();
            alert(x);
            </script>
            

            【讨论】:

            • 虽然这是可能的,并且对它的描述非常好,但我不确定这是一个很好的实践,变量名称通常不应该在不同的用途中重复。跨度>
            【解决方案8】:

            您应该从不重新声明同一范围内的变量,如果您真的想更改它然后分配给它。在这种动态语言中创建不同的对象不需要重新声明,如果您希望 x 是一个字符串,只需分配:

            x = "hello";
            

            您不需要先将其设置回未定义或重新声明。

            请注意,在大多数情况下,更改变量类型并不是很好的做法,只是说明如果这是您需要的,这是一种可能性。

            【讨论】:

              【解决方案9】:

              我最近写了这样的代码:

              var obj1 = get_an_object();
              var v = obj1.get_velocity();
              v += changes_in_velocity();
              obj1.set_velocity(v);
              
              var obj2 = get_an_object();
              var v = obj2.get_velocity();
              v += changes_in_velocity();
              obj2.set_velocity(v);
              

              (实际代码更复杂,重复性更小)

              就浏览器而言,第二个var v 语句是多余且毫无意义的。对我来说,它有两个目的。它说忘记我对旧v 的所有了解,因为这是一种新用法。这意味着我可以重新排序代码,或者注释掉前半部分,而不会破坏任何东西。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-10-13
                • 1970-01-01
                • 2020-04-14
                • 1970-01-01
                • 2020-08-10
                相关资源
                最近更新 更多