【问题标题】:Why are globals bad?为什么全局变量不好?
【发布时间】:2010-11-22 14:17:39
【问题描述】:

在这里使用它对我来说完全有意义。 什么是替代方案?我一般如何避免使用它们,最重要的是为什么根据 jsLint 使用全局变量是不好的。

(function($){
  $(function(){
   $body = $('body'); //this is the BAD Global

   $.each(somearray ,function(){ $body.dosomething() });

   if (something){
     $body.somethingelse();
   }

  });
}(jQuery));

你能帮我理解一下吗?并给我一个更好的解决方案?

【问题讨论】:

    标签: javascript


    【解决方案1】:

    全局变量不好,因为它们不会立即引起问题。只是后来,在你到处使用它们之后,它们会导致非常丑陋的问题——如果不从头开始编写代码,你将无法再解决这些问题。

    示例:您使用$body 定义一些函数。这很好用。但最终,您还需要一个值。所以你使用$body.foo。工作正常。然后添加$body.bar。然后,几周后,您需要另一个值,因此您添加了$body.bar

    您测试了代码,它似乎可以工作。但实际上,您已经“添加”了两次相同的变量。这没有问题,因为 JavaScript 不理解“一次创建新变量”的概念。它只知道“创建,除非它已经存在”。因此,您使用您的代码,最终,一个函数将修改 $body.bar 破坏另一个函数。即使找到问题也会花费你很多时间。

    这就是为什么最好确保只能根据需要查看变量。这样,一个功能就不能破坏另一个功能。随着代码的增长,这一点变得更加重要。

    【讨论】:

      【解决方案2】:

      你应该用 var $body 来定义它,那么它将在该函数的范围内是本地的,没有 var 它可以被每个人覆盖

      (function($){
        $(function(){
         var $body = $('body'); //this is the local variable
      
         $.each(somearray ,function(){ $body.dosomething() });
      
         if (something){
           $body.somethingelse();
         }
      
        });
      }(jQuery));
      

      【讨论】:

      • 或覆盖一些名为 $body 的“其他”全局变量
      • 是的,但是在这个例子中它会替换全局值,这样它只会在函数范围内隐藏它
      • 使用局部变量的函数字面量被声明在与函数定义相同的范围内,称为closure,应该在 jQuery 中广泛使用以达到很好的效果。
      【解决方案3】:

      Globale 变量可能与其他脚本发生冲突或被覆盖。当您不需要全局时,建议避免使用它们。只需使用var(或let,如果您的JS-Version-Support 大于1.7):

      (function() {
        var foo = 'bar';
        alert(foo);
      })();
      

      【讨论】:

        【解决方案4】:

        你可以把它改写成

        var $body = $('body');
        

        那(使用var 关键字)将使它成为一个局部变量,这足以满足您的目的。它仍将在您的each 回调范围内。

        使用全局变量不好的原因是它可以被其他任何东西覆盖。为了使您的代码能够很好地扩展,它取决于您使用的其他脚本。最好让脚本尽可能地自给自足,尽可能少地依赖指向它之外的世界。

        【讨论】:

          【解决方案5】:

          jsLint 非常严格。可能没必要太挂念它。

          但是如果你感觉不好,你可以像你在jQuery的范围内那样做:

          (function($){
            $(function(){
             $.each(somearray ,(function($body){ $body.dosomething() })($('body'));
          
             if (something){
               $('body').somethingelse();
             }
          
            });
          }(jQuery));
          

          【讨论】:

          • 我同意通常没有必要对 jsLint 所说的所有内容都全力以赴,但在这种情况下我不会提到这一点,因为我真的同意如果可以轻松避免全局变量,它们应该是,并且在这段代码中,变量可以声明为局部变量,不需要其他操作。
          猜你喜欢
          • 2014-01-25
          • 1970-01-01
          • 2012-05-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-09-20
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多