【问题标题】:JavaScript scope and closureJavaScript 作用域和闭包
【发布时间】:2010-10-12 11:37:42
【问题描述】:

我正试图绕过闭包(那里有一个笑话),我遇到了这个:

(function () { /* do cool stuff */ })();

这是如何工作的?将函数放在括号中的目的是什么?为什么后面是空括号?

【问题讨论】:

    标签: javascript scope closures


    【解决方案1】:

    关键是在cool stuff 中声明的任何变量都不会在全局命名空间中创建。 javascript 中的任何函数都会创建这样的范围。假设您有一些要运行的 javascript。如果你这样做:

    var b = 1; 
    // stuff using b
    

    而其他一些代码使用 b,它将获得您的剩余价值。 (或者,更糟糕的是,如果其他代码在您的代码运行之前设置 b,然后尝试稍后获取它的旧值,那么您会同时更改它。)

    另一方面,如果你有这段代码,它声明然后调用 a 函数:

    function a() { 
         var b = 1;
    }
    
    a();
    

    稍后一些其他代码使用 b,它不会看到你的值,因为 b 是函数的本地。当然,这样做的问题是您仍在制作一个全局名称 - 在这种情况下为“a”。所以,我们想要一个没有名字的函数——这就是你得到你描述的代码的原因。它声明一个没有名字的函数,然后调用它。

    很遗憾,你不能只说:

    function() { ... }()
    

    因为这会被解析为函数声明语句,然后是语法错误。通过将函数声明包装在括号中,您会得到一个函数表达式,然后可以调用该函数。您可以像任何其他函数表达式(如上面的 a)一样调用它,使用第二组括号。例如,如果函数接受参数,你可以在那里传递它们:

    (function(a) { ... })(1)
    

    【讨论】:

      【解决方案2】:

      创建一个函数,调用它,然后丢弃它。

      如果你这样看可能会更清楚:

      var throwaway = function(){
          // do cool stuff
      };
      throwaway();
      

      这样做是为了创建一个私有命名空间。函数中的代码可以有函数和变量,不用担心与页面中加载的其他代码冲突。

      【讨论】:

      • 当然,除非您与函数名称冲突。
      • 嗯,是的。这就是为什么它通常使用匿名函数来完成。我只是使用了一个命名函数来展示一个更熟悉的形式来做同样的事情。
      • jder 有更好的答案,适合那些迟到的人。
      • @Peter Bailey - 我的意思是 throwaway 中的变量不会冲突,但全局名称“throwaway”可以。
      • jder 扩展了我对闭包的理解,但 Matthew 简短而亲切地回答了我的 3 个问题。谢谢!
      【解决方案3】:

      我最近才看到这篇文章。这种类型的函数定义和调用称为自调用函数

      (function(){  //code })();
      

      函数内的代码将在其定义后立即执行。

      【讨论】:

        【解决方案4】:

        该构造意味着声明一个匿名函数并立即运行它。将代码放在函数体中的原因是因为您在其中定义的变量仍然是函数的本地变量,而不是全局变量。但是,在此函数中定义的闭包仍然可以看到它们。

        【讨论】:

          【解决方案5】:

          函数周围的括号清楚地表明该函数是一个表达式。后面的括号是对函数的调用。

          请注意该函数没有名称。

          【讨论】:

            【解决方案6】:

            一种闭包方法是将变量传递给函数:

            (function($, var_1, var_2) {
                // use JQuery, var_1 and var_2 as local variables
            })($, var_1, var_2);
            

            【讨论】:

              【解决方案7】:

              将函数声明放在括号内会创建一个表达式,该表达式的计算结果为其中的匿名函数。因此,第一个括号计算为一个函数。

              末尾的“空括号”调用定义的函数,因此“//do cool stuff”立即执行。

              这是一种即时执行代码的方法,同时也将变量保持在全局范围之外。

              然而,这里说明的内容与闭包无关——至少不是直接的。闭包是在父函数退出后维护词法范围。

              【讨论】:

                猜你喜欢
                • 2017-06-18
                • 2011-01-19
                • 2014-02-13
                • 2013-01-01
                • 1970-01-01
                • 2018-09-09
                • 1970-01-01
                • 1970-01-01
                • 2010-12-20
                相关资源
                最近更新 更多