Coffeescript中的模块模式与隐藏变量

R. *_* G. 14 javascript design-patterns module coffeescript

深入研究Coffeescript我试图将我的Javascript文件移植到Coffeescript.

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

因此我的问题是:以下JS的含水量Coffeescript会是什么样子:

var test = function () { var hidden = 'open'; return { open: hidden }; }();
Run Code Online (Sandbox Code Playgroud)

分别在Coffeescript中对这种模式有不同/更好的方法吗?

Tre*_*ham 17

我认为最好的方法是在do关键字的帮助下将您的示例逐字转换为CoffeeScript (主要用于捕获循环中的值 - 请参阅我的PragPub文章):

test = do ->
  hidden = 'open'
  open: hidden
Run Code Online (Sandbox Code Playgroud)

这编译成

var test;
test = (function() {
  var hidden;
  hidden = 'open';
  return {
    open: hidden
  };
})();
Run Code Online (Sandbox Code Playgroud)

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


bra*_*ing 6

我在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"
Run Code Online (Sandbox Code Playgroud)

模块助手的实现是

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

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

x = new foo.bar.Amazing
Run Code Online (Sandbox Code Playgroud)

对于你的具体问题,我认为下面的茉莉花规格使用我的模块系统来回答它

@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
Run Code Online (Sandbox Code Playgroud)


AKX*_*AKX 5

CoffeeScript(或者更确切地说,coffee脚本)会自动将代码包装在匿名函数中,除非你告诉它不要.

如果需要从该匿名闭包中发布对象,可以将它们显式分配给根对象; 看一下Underscore.coffee的开头一些指示.

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