【问题标题】:Module Pattern in Coffeescript with hidden Variables带有隐藏变量的 Coffeescript 中的模块模式
【发布时间】:2011-05-24 08:32:00
【问题描述】:

深入研究 Coffeescript 我正在尝试将我的 Javascript 文件移植到 Coffeescript。

关于这个,我有一个与 Doulgas Crockford 的模块模式有关的问题(闭包绑定以保持变量“私有”)

因此我的问题是:以下 JS 的等效 Coffeescript 是什么样的:

var test = function () { var hidden = 'open'; return { open: hidden }; }();

Coffeescript 中的这种模式是否有不同/更好的方法?

【问题讨论】:

    标签: javascript module design-patterns coffeescript


    【解决方案1】:

    我认为最好的方法是在 do 关键字的帮助下将您的示例字面翻译成 CoffeeScript(该关键字的存在主要是为了捕获循环中的值 - 请参阅我的 PragPub article):

    test = do ->
      hidden = 'open'
      open: hidden
    

    编译成

    var test;
    test = (function() {
      var hidden;
      hidden = 'open';
      return {
        open: hidden
      };
    })();
    

    除了格式化之外,它与您的代码相同。 (CoffeeScript 编译器会自动将所有 var 声明放在其作用域的顶部,这样可以通过查看 JavaScript 输出轻松确定变量的作用域。)

    【讨论】:

    • “主要是为了捕获循环中的值” do 的这种特殊行为可以说是最不一致/最令人困惑的功能之一。
    • 烈士,你能解释一下吗? do 关键字对我来说看起来像是在本地范围内捕获值。
    • @matyr 当您最初提出 do 时,这并不是它的预期目的,但这无疑是 Jeremy(不情愿地)将其添加到 CoffeeScript 的原因。见issue 959。这也是do 出现在official docs 中的唯一上下文。
    • 正如我在#788 中所说的那样,该功能破坏了一致性(为什么do(i)->do f=(i)-> 的行为应该不同?)。记录较少的事实只是另一个缺陷(毕竟这是圣诞节的最后一分钟更改)。
    • 他们为什么要这么做。我今天早些时候在 [#960](github.com/jashkenas/coffee-script/issues/960) 注意到了这一点。我当然希望 Jeremy 会选择解决不一致的问题,而不是放弃该功能。
    【解决方案2】:

    我在coffeescript wiki 中添加了一个关于如何处理命名空间的部分。这很优雅(我认为)

    https://github.com/jashkenas/coffee-script/wiki/Easy-modules-with-coffeescript

    Coffeescript 没有高于将所有源代码文件包含在匿名函数中的本机模块系统。但是,通过一些简单的技巧,您可以拥有令 Ruby 羡慕的模块。 我像下面这样定义我的模块

    @module "foo", ->
        @module "bar", ->
            class @Amazing
                toString: "ain't it"
    

    模块助手的实现是

    window.module = (name, fn)->
      if not @[name]?
        this[name] = {}
      if not @[name].module?
        @[name].module = window.module
      fn.apply(this[name], [])
    

    如果你愿意,你可以把它放在另一个源文件中。然后,您可以通过命名空间模块访问您的类

    x = new foo.bar.Amazing
    

    wrt 到您的具体问题我认为下面的茉莉花规格使用我的回答 模块系统

    @module "test", ->
      hidden = 10
      @open  = hidden
    
    describe "test", ->
      it "has no hidden", ->
        expect(test.hidden?).toEqual false
    
      it "has  open", ->
        expect(test.open?).toEqual true
    

    【讨论】:

    【解决方案3】:

    CoffeeScript(或者更确切地说,coffee 脚本)会自动将您的代码包装在一个匿名函数中,除非您告诉它不要这样做。

    如果您需要从该匿名闭包中发布对象,您可以显式地将它们分配给根对象;参考 Underscore.coffee 的开头部分。

    http://jashkenas.github.com/coffee-script/documentation/docs/underscore.html

    【讨论】:

      【解决方案4】:

      如果您可以在单个类中编写模块,那么使用 -b 选项编译咖啡脚本自然会创建您正在寻找的模块模式。

      这个:

      class test
          hidden = 'open'
          open: hidden
      

      编译成这样:

      var test;
      test = (function() {
          var hidden;
          hidden = 'open';
      
          test.prototype.open = hidden;
      
          return test;
      })();
      

      这几乎是您要找的。​​p>

      【讨论】:

        猜你喜欢
        • 2021-02-05
        • 2018-05-08
        • 2011-07-09
        • 1970-01-01
        • 1970-01-01
        • 2014-11-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多