【问题标题】:Returning a global variable from a method从方法返回全局变量
【发布时间】:2014-01-16 00:19:12
【问题描述】:

我想创建一个可以在方法内全局访问的变量。 (我认为我使用了正确的术语)。

以 jQuery 的.hover() 为例。在其中,我试图动态访问一个类名并将其存储在原始.hover()范围之外的其他方法和函数中以供以后操作。

$('elem').hover(function() {
    var classname = $(this)something;
    return classname;
});

console.log(classname);

我正在尝试在全局范围内使用它,因为这会影响更多的方法,而不仅仅是这个。

我确信我应该使用完全不同的编程方法来完成这项工作,但是在方法之外返回值似乎是我的小知识库中唯一可用的过程。

【问题讨论】:

    标签: javascript methods scope


    【解决方案1】:

    你有几个选择:

    1. 在代码周围使用范围函数,并在该范围函数中使用局部变量。作用域函数的所有函数都可以访问这些变量:

      (function() {
          var classname = "";
      
          $('elem').hover(function() {
              classname = this.className;
          });
      
          $('some other elem').on('some-other-event', function() {
              console.log(classname);
          });
      })();
      

      注意第二个事件处理程序如何访问hover 处理程序可以访问的同一变量。在这两种情况下,它们都有一个对变量的持久引用,而不是变量的副本。更多:Closures are not complicated.

    2. 使用全局变量,基本上只是上面的一个特例。

    我推荐#1。这是一个完整的例子:Live Copy | Source

    <!DOCTYPE html>
    <html>
    <head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
    <meta charset=utf-8 />
    <title>Simple Closure</title>
      <style>
        .a, .b, .c {
          width: 60px;
          border: 1px solid black;
        }
      </style>
    </head>
    <body>
      <p>Hover over these:</p>
      <div class="a">a</div>
      <div class="b">b</div>
      <div class="c">c</div>
      <script>
        (function() {
          var prevClassHovered = "";
          var lastClassHovered = "";
    
          // Remember the last hovered thing
          $(".a, .b, .c").hover(function() {
            lastClassHovered = this.className;
          });
    
          // Output the last one every ~500 ms, if it's
          // changed. Here the event in question is a
          // timer event, but of course it can be anything.
          setInterval(function() {
            if (prevClassHovered !== lastClassHovered) {
              prevClassHovered = lastClassHovered;
              display(lastClassHovered);
            }
          }, 500);
    
          function display(msg) {
            var p = document.createElement('p');
            p.innerHTML = String(msg);
            document.body.appendChild(p);
          }
        })();
      </script>
    </body>
    </html>
    

    【讨论】:

    • 感谢非常详细的回答。这真的很有帮助。我不明白为什么最后会有第二个()。这样做的目的是什么?此外,这是我第二次看到 msg 传递给函数。这是特殊的,还是我可以使用任何变量?
    • @ShawnStrickland:接近尾声的()调用匿名函数。没有它们,它只是一个函数表达式,定义了一个任何东西都不会调用的函数,因此函数中的代码永远不会运行。例如,(function() { console.log("You never see this"); }).
    • 使用全局变量是否有任何危险,尤其是在没有var关键字的情况下定义一些东西,在过程中节省一些行?
    • @ShawnStrickland:在浏览器中,全球 JS 环境非常拥挤。每个带有id 的元素都被丢弃在其中,一些浏览器也这样做names,有一堆预定义的全局变量......我主张完全避免全局变量。通过不使用 var 重新“保存行”:您不保存任何行。您保存 1-4 个字符(var 第一个字符为 4,每个 , 为 1 个)。如果要保存字符,请使用压缩器/压缩器。 Horror of Implicit Globals 就是这样,我建议使用严格模式来避免它。
    【解决方案2】:

    你必须做类似的事情

    var classname;
    
    $(document).ready(function () {
        $('elem').hover(function () {
            classname = $(this) something;
            console.log(classname);
        });
        $('elem').click(function () {
            console.log(classname);
        })
    });
    
    
    
    console.log(classname);
    

    现在你可以在任何地方使用它

    【讨论】:

    • 当我尝试这个时,第二个函数 - click 函数 - 似乎没有注册,最后一次调用登录到控制台返回 undefined。
    • 我确实让它工作了,但是 console.log(classname);从来不想工作。我可以在控制台中调用类名变量,但不能让它自己调用。是因为我们仅将其绑定到悬停状态吗?它会在悬停开始之前立即自行启动?
    【解决方案3】:

    您可以通过在函数外部定义变量或通过window.varName = 'value' 定义变量来定义全局变量。例如:

    $('elem').hover(function() {
        window.classname = $(this)something;
        return classname;
    });
    

    然后变量类名将被全局定义,您可以通过简单地将其视为任何其他变量来调用它。您无需在每次调用时都添加 window.

    或者,就像 nzn 说的那样,您可以在函数外部定义变量,然后分配一个新值而不在其前面加上 var。例如:

    var classname;
    $('elem').hover(function() {
        classname = $(this)something;
        return classname;
    });
    

    这将与window. 方法完全相同,但在这种情况下,您首先需要在函数外部定义变量,而您不需要使用window.classname 来执行此操作。请记住,您应该注意全局变量。在调用全局值之前,您应该 100% 确定在调用它时定义了变量。如果不确定是否定义,那么在函数外定义变量的方法肯定更好。

    【讨论】:

    • 这是一个不错的捷径!我很欣赏你的阐述。
    猜你喜欢
    • 1970-01-01
    • 2014-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-16
    • 2021-11-07
    相关资源
    最近更新 更多