【问题标题】:Will I have any problems if I declare the same variable multiple times?如果我多次声明同一个变量,我会有什么问题吗?
【发布时间】:2012-11-17 19:08:30
【问题描述】:

假设我有一些代码:

//Javascript
var elements = [];
function addNumbah1(){
    var i = 1;
    elements.push(i);
}
function addNumbah2(){
    var i = 2;
    elements.push(i);
}

直到 addNumbah999(),每次都声明 i 变量是不是不好的形式?那会破坏什么吗?我应该这样做:

//Javascript
var elements = [];
var i
function addNumbah1(){
    i = 1;
    elements.push(i);
}
function addNumbah2(){
    i = 2;
    elements.push(i);
}

【问题讨论】:

  • 您的两种语法不等价。您需要一个还是三个变量?
  • 在函数中声明变量使它们成为该函数的本地变量 - 在第二个示例中,您在全局范围内声明变量
  • 您的第一个函数在每个函数中声明一个本地 i。每次您拨打addNumbah1()i 将是1。第二个全局声明 i 并在每个函数中使用全局,尽管在每次调用时都重置为新值。
  • @ÁlvaroG.Vicario 你能澄清一下你的意思吗?
  • @kinakuta 像这样一遍又一遍地改变全局值是不好的形式吗?还是可以?

标签: javascript variables


【解决方案1】:

简短回答:,JS 将所​​有变量声明提升到范围的顶部,无论您声明了多少次:

var i = 0
for (var i=0;i<10;i++)
{
    var j = i%2;//declared 10 times, on each iteration
}

将被翻译成

var i, j; //i is undefined at this point in the code.
for (i = 0;i<10;i++)
{
    j = i%2;//declared 10 times, on each iteration
}

在您的第一个示例中,您将i 声明为函数范围内的变量,这是您必须 执行的操作以避免混乱全局范围。这些变量使用的内存在函数被调用时分配,并在函数返回时释放(粗略地说,closures 形成一个异常,但这会让我们走得更远)。考虑一下:

var i = 10;
function someF()
{
    var i = 1;
    alert(i);
}
someF();//alerts 1 <-- value of i, local to someF
alert(i);//10, global i is unchanged

但是如果你省略了var:

function someF()
{
    i = 1;
    alert(i);
}

您会看到 1 收到两次警报。如果 JS 在当前作用域中找不到变量声明,它将在更高的作用域中查找,直到找到 var。如果没有找到变量,JS 会在最高范围(全局)为你创建一个。 Check my answer here 关于隐含全局变量如何工作的更详细示例,或 read the MDN pages,尤其是关于名称冲突

的部分

最后,我想补充一点,全局变量,尤其是隐含的全局变量,是邪恶的。还要知道 ECMA6 标准显然正在远离全局变量,并引入了对真正块作用域的支持。 As you can see here
哦,如果你想检查一个函数是否使用隐含的全局变量:'use strict'; 是个好东西:

(function()
{
    'use strict';
    var localVar = 123;//ok
    impliedGlobal = 123;//TypeError!
}());

如您所见,不允许使用隐含的全局变量。完整说明见MDN on strict mode

【讨论】:

  • 很好且描述完整的答案。它当然值得我投票
  • 谢谢!第一个完整且完整地给出答案以及原因的人。
【解决方案2】:

您可以多次声明一个变量。在您的代码中,您在此处在不同的范围内声明变量 i:

   //Here you are declaring variable i local to addNumbah1,2 functions 
   var elements = [];
   function addNumbah1(){
       var i = 1; 
       elements.push(i);
   }
   function addNumbah2(){
       var i = 2; 
       elements.push(i);
   } 


   //Here v /variable i has been declared globally
   var elements = [];
   var i
   function addNumbah1(){
       i = 1;   
       elements.push(i);
   }
   function addNumbah2(){
       i = 2;  
       elements.push(i);
   }

请注意,虽然您可以多次声明一个变量,但通常这不是一个好的编程习惯,因为它可能会导致您的应用程序出现错误/问题

【讨论】:

  • 你没有在这里重新声明任何变量,你正在使用隐含的全局变量!不要
  • @EliasVanOotegem 朋友,我并没有自己声明。我只是想通过粘贴他的代码并在 cmets 中描述全局和本地范围来帮助发布此问题的人
  • 当我评论时,第一个 sn-p 还没有——只是一个全局的例子,以及每次重置变量的解释(这根本不是真的:只有声明被提升。表达式不能被提升,这就是为什么 IIFE 需要 !~() 位:将函数转换为表达式)
  • 对不起,我是迂腐的,但我今天刚刚在研究这些东西,because of this question。无论如何:快乐的编码。再一次,很抱歉对此如此迂腐
  • @EliasVanOotegem 我称你为朋友 :-) 所以不要抱歉。我知道你比我更清楚。你只是帮助我提高了:-)
【解决方案3】:

在函数内声明的变量只存在于该函数的范围内,因此在不同的函数中使用相同的变量名不会破坏任何东西。

事实上,将变量保持在尽可能小的范围内是一种很好的形式!全局变量可能难以管理,并且会产生非常糟糕的错误,尤其是当另一个函数尝试访问该变量时一个函数没有使用该变量时。

专门针对简单变量,声明

var i = 0;

每次都很好。

【讨论】:

    【解决方案4】:

    可以在不同的函数中声明同名的变量。

    【讨论】:

      【解决方案5】:

      你做的第一种方法很好。 i 的每个实例都不知道其他函数中的另一个 i。

      你应该在global versus local variables阅读本教程

      另外,我可以建议一个优化。为什么不能只执行以下操作来覆盖任何数字(而不是每个数字的单独函数)?

      var elements = [];
      function addNumbah(number){
          elements.push(number);
      }
      

      【讨论】:

        【解决方案6】:

        第二种形式,全局i实际上可能会慢一些,因为它是在更高的范围内定义的,而在更高范围内定义的变量需要更长的时间来解析。

        除了性能方面的考虑之外,只要坚持通用准则,除非性能确实是个问题。在这种情况下:尽可能缩小变量范围

        我强烈建议您使用第一种形式。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-12-03
          • 2023-01-16
          相关资源
          最近更新 更多