Шаблон модуля в Coffeescript со скрытыми переменными

Копаем в Coffeescript Я пытаюсь портировать файлы Javascript в Coffeescript.

В связи с этим у меня есть вопрос, связанный с шаблоном модуля Doulgas Crockford (привязка привязки для сохранения переменных "private")

Поэтому мой вопрос: что бы выглядел аквивалентный Coffeescript для следующего JS:

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

Соответственно, есть ли другой подход к этому шаблону в Coffeescript?

Ответы

Ответ 1

Я думаю, что лучший подход - буквально перевести ваш пример на CoffeeScript с помощью ключевого слова do (который существует в основном для захвата значений в циклах - см. статью PragPub):

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

Скомпилируется

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

который идентичен вашему коду, отличному от форматирования. (Компилятор CoffeeScript автоматически помещает все объявления var в начало своей области действия, что позволяет легко определить, как изменяется переменная, просматривая вывод JavaScript.)

Ответ 2

Я добавил раздел в wiki coffeescript о том, как я обрабатываю пространство имен. Это довольно элегантно (я думаю)

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

Ответ 3

CoffeeScript (вернее, coffee script) автоматически обертывает ваш код в анонимной функции, если вы не сообщите об этом не.

Если вам нужно публиковать объекты из этого анонимного закрытия, вы можете явно назначить их корневому объекту; см. начало Underscore.coffee для некоторых указателей.

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

Ответ 4

Если вы можете написать свой модуль в одном классе, то компиляция coffeescript с опцией -b, естественно, создаст шаблон модуля, который вы ищете.

Это:

class test
    hidden = 'open'
    open: hidden

компилируется:

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

    test.prototype.open = hidden;

    return test;
})();

что очень похоже на то, что вы искали.