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

时间:2011-05-24 08:32:00

标签: javascript module design-patterns coffeescript

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

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

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

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

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

4 个答案:

答案 0 :(得分:17)

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

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

这将编译为

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

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

答案 1 :(得分: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"

模块助手的实现是

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

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

@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

答案 2 :(得分:5)

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

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

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

答案 3 :(得分:1)

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

此:

class test
    hidden = 'open'
    open: hidden

编译到:

var test;
test = (function() {
    var hidden;
    hidden = 'open';

    test.prototype.open = hidden;

    return test;
})();

这几乎就是你要找的东西。