Модуль Pattern в Coffeescript со скрытыми переменными - PullRequest
14 голосов
/ 24 мая 2011

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

В связи с этим у меня есть вопрос, связанный с модульным шаблоном Дулгаса Крокфорда (привязка замыкания, чтобы переменные были «приватными»)

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

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

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

Ответы [ 4 ]

17 голосов
/ 24 мая 2011

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

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

Компилируется в

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

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

6 голосов
/ 06 июля 2011

Я добавил раздел в 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
5 голосов
/ 24 мая 2011

CoffeeScript (или, скорее, скрипт coffee) автоматически оборачивает ваш код в анонимную функцию, если вы не запретите.

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

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

1 голос
/ 04 октября 2012

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

Это:

class test
    hidden = 'open'
    open: hidden

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

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

    test.prototype.open = hidden;

    return test;
})();

что очень близко к тому, что вы искали.

...