13

I have a class written in coffeescript, e.g.,

class Example
  constructor: ->
    $.each [1, 2, 3], (key, value) =>
      @test = value
    return @test
  render: ->
    alert @test

and I have this class as a separate file, Example.coffee

Now I want to be able to instantiate in my main javascript file like so:

d = new Example
d.render()

but the class is undefined even when it is included as a script on the page, like

<script src="Example.js></script>
<script src="main.js"></script>

How do you make the class publicly available to the main file?

1

3 Answers 3

28

You can declare your class to be globally accessible (at least for browsers) by declaring it to be in the window namespace:

class window.Example
  constructor: ->
    $.each [1, 2, 3], (key, value) =>
      @test = value
    return @test
  render: ->
    alert @test

That will put Example straight into window. You can also say class @Example in most cases.

By default, CoffeeScript wraps each file in a (function() { ... })() wrapper to prevent namespace pollution. You can prevent this by supplying -b when compiling your CoffeeScript:

-b, --bare
Compile the JavaScript without the top-level function safety wrapper.

but that might not be an option for you (or it might be an ugly one). The usual approach is to declare an application specific namespace somewhere before your classes are loaded:

// Probably in a <script> in your top-level HTML...
App = { };

and then namespace your classes appropriately:

class App.Example
    #...

Then refer to everything through the App namespace.

Sign up to request clarification or add additional context in comments.

2 Comments

Is there anyway to setup the namespace without having to resort to a script tag? Didn't get very far in my attempts. Thanks!
@MichaeldeSilva: In a browser environment you can say things like @App ?= { } before your classes to initialize window.App if it isn't already around. Or you could say class @C to put your classes in the global scope if that fits. Or you could use a module system like require.js.
13

I know this is an old thread, but in case anyone else finds it useful, declare your class with "@" and it will be accessible to .js files outside of the .coffee file.

So, in example.coffee:

class Introverted
  honk: ->
    alert "This class is visible within the .coffee file but not outside"

class @Extroverted
  honk: ->
    alert "This class is visible inside and outside of the .coffee file"

That is compiled to example.js which can then be used in example.html:

<script src="example.js"></script>
<script>
var p = new Extroverted(); // works fine
p.honk();

var i = new Introverted(); // will fail with "Introverted is not defined"
i.honk();
</script>

2 Comments

This is effectively the same as mu is too short's answer. The @Extroverted will compile to this.Extroverted, which is effectively the same as window.Extroverted in this case.
Just to add to Nick's comment above, in case anyone is wondering... the reason why this works is because @ is a shortcut for this. in coffeescript. And like he says, in the above context this is window so you're attaching Extraverted to window, effectively making it global.
4

Create a global variable

window.Example = Example

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.