6

I saw this pattern in the underscore source code and many other open source JavaScript projects :

(function() {
 // the library code
}).call(this);

Anyone can explain what this pattern do ? and what is the benefits of using it ?

Why not just :

(function() {
 // the library code
}());
2
  • 2
    It sets this inside the function to the same as this outside the function. (This usually is ran globally, so this is window.) Commented Jan 27, 2014 at 17:06
  • That doesn't explain it since, for underscore.js, this is the same in both cases. Commented Jan 27, 2014 at 17:19

4 Answers 4

3

Since both are equivalent in normal context I looked into the source and it was changed from the form you suggest to the current form 2 years ago with the following check-in comment:

"Added explicit definition of global context for compatibility with Adobe JS"

https://github.com/jashkenas/underscore/commit/aa916b8cfe565dc206d85c4cb74fbb6c499067a7

The check-in logs for the first version of Underscore with this change claims "Improved Underscore compatibility with Adobe's JS engine that can be used to script Illustrator, Photoshop, and friends."

http://underscorejs.org/ Version 1.4.3

So this change seems to have been made because Adobe's JavaScript engine did not conform to ES3 or ES5 at the time but with this change Underscore was made compatible with their variant.

If you are not planning on running your module in Adobe JS then you can use either form. If you are then it appears Adobe JS requires the form used by Underscore.

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

Comments

0

It's probably to do with the noConflict feature if you happen to have multiple versions of underscore running at the same time.

this (window) is passed in so it can detect existing versions of _. Using this notation you avoid a hard reference to window, which is nice. There are also some minor performance benefits: variables in local scope resolve faster.

Alternatives could be:

(function () {
    // library
}(window)); // hard reference to window (not so nice)

(function () {
    // library
}({})); // this will break `noConflict` detection

Comments

0

This is to wrap you whole code in an anonymous function. This way variable declared inside the function will remain private, so other scripts won't be able to access your code.

And .call is a function method. That will invoke the anonymouse function with passed argument as a value of this.

In this case whatever is the value of this is by default it's window object, will be available inside the anonymouse function to. Here is an example of it.

(function(a, b, c ){ // and other arguments
    // Here `this` will refer to document object.

    // And the variables declared here are compltly private

    // If you want any variable to make global use window object

    var someStuff = 'scret'; // Private

    function Lib(){
        return someStuff.length;
    }

    window.Lib = Lib; // This will be available to other scripts

}).call(document, a, b, c);

This kind of wrapper is generally generated by preprocessor languages like CoffeeScript

Comments

0

First part:

var x = 1; // `x` is in the global scope

(function() {
 var y = x; // `y` is in the current function's scope
}());

x = y; // Here `x` becomes `undefined` because `y` is not declared in this "outer" scope

As to the "why" - it's a simple technique to keep out of trouble (no "memory leaks" [all internally declared vars are void when function ends], no declaration collision etc').

Second part: As for the call (there's also apply which is similar) version, it's simply a matter of context.
The author wants that the context of the anonymous function (that function above) will have its this point to the same this of the outer scope.

Hope it's clear :)

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.