【问题标题】:Confusing Javascript class declaration令人困惑的 Javascript 类声明
【发布时间】:2011-02-03 12:16:06
【问题描述】:

我有一些第三方 Javascript 有这样的语句:

FOO = function() {
   ...functions() ... 
   return { hash }
}();

它按设计工作,但我对此感到困惑。谁能定义这个结构在做什么?创建类只是一种奇怪的方式吗?

【问题讨论】:

    标签: javascript


    【解决方案1】:

    您缺少一个开放的括号,但它基本上是一种通常在对象中隐藏信息的方式,即一种设置私有和私有方法的方式。

    例如

    var foo = (function() {
       /* function declarations */
       return { /* expose only those functions you 
                   want to expose in a returned object 
                */ 
              }
    })();
    

    看看 Papa Crockford 的 Private Members in JavaScript。这基本上就是您所看到的模式,但形式略有不同。函数声明被包装在一个自调用匿名函数中——一个在声明后立即执行的匿名函数。由于其中的函数作用域为匿名函数,因此在匿名函数执行后它们将无法访问,除非它们通过在匿名函数执行返回的对象中引用它们而创建的闭包暴露出来。

    一般称为the Module Pattern

    【讨论】:

    • 您不需要右括号来平衡左括号吗?另外,省略那对会有什么后果?该函数不会仍然是匿名的吗?
    • 看起来额外的括号只是风格。见adequatelygood.com/2010/3/…
    • @brainjam - 谢谢,错过了最后的括号。在这种情况下,它们是可选的,但如果您想在全局范围内执行函数而不将其分配给变量,则不是。为了保持一致性并避免“在这种情况下我需要它们/在这种情况下我不需要它们吗?”困境,我建议在立即调用匿名函数时始终使用它们。
    【解决方案2】:

    最后的参数使它成为Module Pattern,这基本上是一种在使用私有变量和函数的同时拥有对象的单个实例(Singleton)的方法。

    由于有闭包hash,如果它本身是一个对象或函数,将可以访问在该匿名单例对象中声明的所有变量。

    【讨论】:

      【解决方案3】:

      这是一种使用闭包的技术。这个成语是众所周知的,但当你第一次看到它时会感到困惑。 FOO 定义为最外层 function() 返回的对象。注意末尾的括号,它导致函数计算并返回{ hash }

      代码相当于

      function bar() {
         ...functions() ... 
         return { hash }
      };
      
      FOO = bar();
      

      所以 FOO 等于 { hash }。这样做的好处是hash,无论它是什么,都可以访问function() 中定义的内容。没有其他人可以访问,因此这些内容本质上是私有的。

      谷歌“Javascript 关闭”以了解更多信息。

      【讨论】:

      • 您的示例遗漏的模式的另一个重要点是自调用匿名函数避免污染全局命名空间,即以您为例,在全局范围内不会有条形 function直接调用。
      • 当然。我只是想从概念上“解析”它。但是,是的,一旦你理解了这部分,你会想在不定义 bar 的情况下将它重新组合起来。
      【解决方案4】:

      Js 本身并没有真正的类,而是“原型”。这意味着在正常类型安全的意义上,没有两个对象具有相同的“类型”,并且您可以动态地将成员添加到一个实例,同时不影响另一个实例。 (这就是他们所做的)。

      信不信由你,他们使用的语法可能是最清晰的,因为它不会试图隐藏在某些 C 风格的类语法后面。

      Doug Crockford 的 Javascript: The Good Parts 是一本快速阅读的书,也是我遇到的关于 js 中 OOP 的最佳介绍。

      【讨论】:

        【解决方案5】:

        这实际上不是一个类,只是一个对象。我建议阅读以下内容:http://javascript.crockford.com/survey.html

        因为 JavaScript 没有块作用域,您的选择是(大多数情况下)让所有变量都驻留在全局或函数作用域中。你的 sn-p 的作者想要声明一些他不想在全局范围内的局部变量,所以他声明了一个匿名函数并立即执行它,返回他试图创建的对象。这样所有的变量都将在函数的范围内。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-06-13
          • 2011-07-24
          • 1970-01-01
          • 2019-01-31
          • 2021-04-23
          • 2019-12-23
          • 2013-01-04
          相关资源
          最近更新 更多