Reputation: 1768
I want to use the 'class' syntax to create a class, and when it news an instance, the instance can be directly used as a Function.
class Foo
constructor: (@bar) ->
baz: ->
console.log 'baz'
...
f = new Foo 'bar'
f() # runs () -> console.log @bar
f.baz() # 'baz'
Here is a JavaScript solution but I cannot reproduce it in CoffeeScript using class syntax.
Upvotes: 2
Views: 1399
Reputation: 231355
Here's an variation on Bergi's
answer:
class Foo
constructor: (@bar) ->
foo = () =>
console.log @bar
foo.baz = ->
console.log 'baz'
return foo
f = new Foo 'bar'
f()
f.baz()
This may just be using class
as a wrapper, much as do()
does. f
is { [Function] baz: [Function] }
. Also Foo 'bar'
(without the new
), produces the same thing.
Upvotes: 0
Reputation: 231355
I don't think you can write a Coffeescript class which compiles to that Javascript (or something close). The Coffeescript class
insists on 2 things:
It ends the class body with return AwesomeObject;
If I put a return bar
in the class body, it objects with error: Class bodies cannot contain pure statements
.
The linked Javascript model is:
var AwesomeObject = (function() {
var AwesomeObject = function() {...};
...
return function() {
var o = new AwesomeObject();
...};
})();
It defines an AwesomeObject
constructor internally, but returns a different function. This is clearer if the internal name is changed to AwesomeObject1
. It functions the same, but there is no way of accessing AwesomeObject1
directly.
Also AwesomeObject()
and new AwesomeObject()
return the same thing.
{ [Function]
whatstuff: 'really awesome',
doStuff: [Function] }
The compiled Coffeescript (for class AwesomeObject...
) instead is:
AwesomeObject = (function() {
function AwesomeObject() {...}
...
return AwesomeObject;
})();
P.S.
https://github.com/jashkenas/coffee-script/issues/861
Coffeescript issue discussion on new Foo()
versus Foo()
syntax. Consensus seems to be that while new-less
calls are allowed in Javascript for objects like Date
, it isn't encouraged for user defined classes. This is interesting, though not really relevant to the question here.
Upvotes: 3
Reputation: 664297
This is what you're looking for:
class Foo
constructor: (@bar) ->
f = -> console.log bar
for v, k of @
f[v] = k
return f
baz: ->
console.log 'baz'
f = new Foo 'bar'
f() # runs () -> console.log @bar
f.baz() # 'baz'
Notice that this solution does not return a callable object which inherits from Foo.prototype
(which is impossible), but that it does return a Function
object in which some properties are mixed in.
A better pattern would be not to return a callable function object, but to return a standard object instance that has a call
or execute
method.
Upvotes: 0
Reputation: 5515
How about something like this:
class Foo
constructor: (@bar) ->
return => console.log @bar
f = new Foo 'bar'
f()
Upvotes: 0