14

I recently started using coffeescript and was curious what is the "right" way to expose an object that I create with Coffeescript to other javascript pages. Because of coffeescripts wrapping functionality, is it acceptable behavior to call window.coffeeObject = externalObject.

Example

example.coffee

externalObject = 
   method1: -> 'Return value'
   method2: -> 'Return method2'

window.myApi = externalObject

example.js -- compiled from example.coffee

(function() {
  var externalObject;
  externalObject = {
    method1: function() {
      return 'Return value';
    },
    method2: function() {
      return 'Return method2';
    }
  };
  window.myApi = externalObject;
}).call(this);

other.js

alert(myApi.method1()) // Should return "Return value"
brent
  • 1,709
  • 2
  • 13
  • 15

2 Answers2

5

Yep that's correct. Alternatively you can use define @myApi = { foo: -> } because this is window in the root context of the file.

Alex Wayne
  • 178,991
  • 47
  • 309
  • 337
  • `window.foo` also has the advantage of making it very _explicit_ that your injecting it into global scope. – Raynos May 13 '11 at 17:29
  • I'm guessing using the @ symbol is better because then it's portable for your node.js scripts as well, correct? – brent May 13 '11 at 17:30
  • 1
    Quite right. Either `window` or `this` will work fine; stylistically, I think `window`. is preferred. You'll thank yourself if you find yourself grepping for global exports... (**Edit to respond to simul-post with brent**: Yes, `this` will automatically resolve to `exports` in Node. Note that I like to define something like `root = exports ? this` to allay any possible confusion.) – Trevor Burnham May 13 '11 at 17:32
4

You can simplify the syntax further, for example if you had 2 internal functions

example.coffee

myPrivateFunction = ->
    "return 1"

myPrivateFunction2 = ->
    "return 2"

@myApi = {
    myFunction : myPrivateFunction,
    myFunction2 : myPrivateFunction2
}

example.js

this.myApi = {
  myFunction: myPrivateFunction,
  myFunction2: myPrivateFunction2
};

The @ will be window within the main scope of the file.

Then call from elsewhere by window.myApi.myFunction()

If you wanted to map the external function names to the same internal names, if you don't specify key : value pairs, it will just use the string value as the key by default.

example.coffee

@myApi = {
    myPrivateFunction,
    myPrivateFunction2
}

example.js

this.myApi = {
  myPrivateFunction: myPrivateFunction,
  myPrivateFunction2: myPrivateFunction2
};
Ryan
  • 5,416
  • 1
  • 39
  • 36