Pattern for CoffeeScript modules

<>

This question already has an answer here:

Answers


Harmen's answer is quite good, but let me elaborate a bit on where this is done by the CoffeeScript compiler and why.

When you compile something with coffee -c foo.coffee, you will always get a foo.js that looks like this:

(function() {
  ...
}).call(this);

Why is that? Well, suppose you put an assignment like

x = 'stringy string'

in foo.coffee. When it sees that, the compiler asks: Does x already exist in this scope, or an outer scope? If not, it puts a var x declaration at the top of that scope in the JavaScript output.

Now suppose you write

x = 42

in bar.coffee, compile both, and concatenate foo.js with bar.js for deployment. You'll get

(function() {
  var x;
  x = 'stringy string';
  ...
}).call(this);
(function() {
  var x;
  x = 42;
  ...
}).call(this);

So the x in foo.coffee and the x in bar.coffee are totally isolated from one another. This is an important part of CoffeeScript: Variables never leak from one .coffee file to another unless explicitly exported (by being attached to a shared global, or to exports in Node.js).

You can override this by using the -b ("bare") flag to coffee, but this should only be used in very special cases. If you used it with the above example, the output you'd get would be

var x;
x = 'stringy string';
...
var x;
x = 42;
...

This could have dire consequences. To test this yourself, try adding setTimeout (-> alert x), 1 in foo.coffee. And note that you don't have to concatenate the two JS files yourself—if you use two separate <script> tags to include them on a page, they still effectively run as one file.

By isolating the scopes of different modules, the CoffeeScript compiler saves you from the headache of worrying whether different files in your project might use the same local variable names. This is common practice in the JavaScript world (see, for instance, the jQuery source, or just about any jQuery plugin)—CoffeeScript just takes care of it for you.


The good thing about this approach is that it creates private variables, so there won't be any conflict with variable names:

(function() {
  var privateVar = 'test';
  alert(privateVar); // test
})();

alert(typeof privateVar); // undefined

The addition of .call(this) makes the this keyword refer to the same value as it referred to outside the function. If it is not added, the this keyword will automatically refer to the global object.

A small example to show the difference follows:

function coffee(){
  this.val = 'test';
  this.module = (function(){
    return this.val;
  }).call(this);
}

var instance = new coffee();
alert(instance.module); // test

function coffee(){
  this.val = 'test';
  this.module = (function(){
    return this.val;
  })();
}

var instance = new coffee();
alert(typeof instance.module); // undefined

This is similar syntax to this:

(function() {

}());

which is called an immediate function. the function is defined and executed immediately. the pros to this is that you can place all of your code inside this block, and assign the function to a single global variable, thus reducing global namespace pollution. it provides a nice contained scope within the function.

This is the typical pattern i use when writing a module:

var MY_MODULE = (function() {
    //local variables
    var variable1,
        variable2,
        _self = {},
        etc

    // public API
    _self = {
       someMethod: function () {

       }
    }

    return _self;
}());

not sure what the cons might be exactly, if someone else knows of any i would be happy to learn about them.


Need Your Help

Sending email using Zend Framework and PHP

php email zend-framework send

I working on a form whereby when the user enter in their email account and click on send, an email will be sent to their email account.

What does square bracket [] mean in the below code?

c# asp.net sharepoint sharepoint-2007

I got below code from http://msdn.microsoft.com/en-us/library/dd584174(office.11).aspx for adding custom property in webpart tool pane. What does square bracket ([]) mean in the below code?