0

I have been writing javascript for a while now and more recently been playing with coffeescript. I noticed that coffeescript compiles functions in the following way:

(function() {

}).call()

I have also noticed people write functions in this way:

(function() {

})()

From what I understand these are anonymous functions that call themselves. Firstly, what is the difference in between having .call() and just () is .call() just a more semantic way of writing ().

Also why does coffeescript wrap the entire file in an anonymous function, when it isn't usually necessary? Are there any performance or other advantages to this? When should these sort of self calling anon functions be used?

Thanks

Melbourne2991
  • 11,707
  • 12
  • 44
  • 82

1 Answers1

5

Using .call() changes the context of the IIFE to the this value of the parent scope.

The first this will be [object Window], the global scope in browser environments:

(function () {

    console.log(this);

})();

The second, will be the exact same:

(function () {

    console.log(this);

}).call(this);

The difference is that in ECMAScript 5's strict mode, the first example this will be undefined:

(function () {

    'use strict';

    console.log(this); // undefined

})();

However when using Strict Mode and .call(), this is again the global scope with the correct this context:

(function () {

    'use strict';

    console.log(this);

}).call(this);

Here's a jsFiddle showing this. The main difference is that the normal IIFE loses it's this context, some CommonJS platforms evaluate files with a specific this.

CoffeeScript does this to ensure that your code has the same this context as the scope where it's placed (the parent scope) - because functions don't normally inherit their this object from the surrounding context.

Using the pattern(s) above, you should wrap your function logic in there to avoid placing all your code in the global scope and having variable/naming conflicts, to which you can then create things such as Modules and return only the APIs that you need, for instance:

var Module = (function () {

    'use strict';

    return {
        someMethod: function () {
            // do something
        }
    }

})();

// call it:
Module.someMethod();

Each function creates it's own scope, so wrapping your blocks of code in these will protect your variable/function names from conflicting with eachother. We can also access "private" methods from within these closures:

var Module = (function () {

    'use strict';

    var _privateMethod = function () {};

    return {
        someMethod: function () {
            _privateMethod();
        }
    }

})();

We would do this when we don't want the methods to be publicly accessible by our users too.

Todd Motto
  • 903
  • 6
  • 10