문제

I'd like mock out MarkdownDeep, I've the following code, in JavaScript

MarkdownDeep = new (function () {
    this.Markdown = function () {
        this.Transform = function (a) {
            return "html";
        };
    };
})();

but I'm having trouble implementing this in CoffeeScript

I tried the following

MarkdownDeep = new (->
  @Markdown = ->
    @Transform = (a) ->
      "html"
)()
window.MarkdownDeep = MarkdownDeep

but it doesn't work, specifically in my unit test markdown = new MarkdownDeep.Markdown() gives "undefined is not a function", though the JS version mocks out fine.

도움이 되었습니까?

해결책

Your example results in the following javascript code:

var MarkdownDeep;
MarkdownDeep = new (function() {
  return this.Markdown = function() {
    return this.Transform = function(a) {
      return "html";
    };
  };
});
window.MarkdownDeep = MarkdownDeep;

The line return this.Markdown = function() { /* ... */ } makes the function the object returned by the new operator.

Writing

MarkdownDeep = new (->
  @Markdown = ->
    @Transform = (a) ->
      "html"
    return
  return
)
window.MarkdownDeep = MarkdownDeep

fixes the problem.

Addition: This answer mentions the algorithm for object construction in javascript

다른 팁

CoffeeScript's implicit returns can lead to mayhem when used in conjunction with new. As others have pointed out, you could use explicit returns. Another option is to use class, which creates a function (the constructor) with no implicit return:

MarkdownDeep = new class
  constructor: ->
    @Markdown = class
      constructor: ->
        @Transform = (a) ->
          'html'

Of course, that's not very readable in this case, but as a general rule, you'll save yourself headaches by using class whenever you use new.

You need to explicitly set a return value for your objects/classes or else it will return the member functions when creating a new instance.

JS FIDDLE

MarkdownDeep = new (->
  @Markdown = ->
    @Transform = (a) ->
      "html"
    undefined #return undefined instead of this.Transform
  undefined #return undefined instead of this.Markdown
)

markdown = new MarkdownDeep.Markdown()
alert markdown.Transform()

compiles to:

var MarkdownDeep, markdown;
MarkdownDeep = new (function() {
  this.Markdown = function() {
    this.Transform = function(a) {
      return "html";
    };
    return;
  };
  return;
});
markdown = new MarkdownDeep.Markdown();
alert(markdown.Transform());

This is what Coffeescript gives as output

var MarkdownDeep;
MarkdownDeep = new (function() {
  return this.Markdown = function() {
    return this.Transform = function(a) {
      return "html";
    };
  };
});

The last line in every function is implicitly returned in Coffeescript. Checking this in the console yields MarkdownDeep as

function () {
    return this.Transform = function(a) {
        return "html";
    };
}

which returns a function that does not have Markdown() as a method.

CoffeeScript automatically wraps each output file in an anonymous function ((function() { ... })()). To disable this use the --bare or -b option when running coffee.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top