Wrapping Libraries | jQuery vs. Backbone

backbone.js, javascript, jquery

Solution

It helps preserving the value of `this` in the inner function.

A call to an unbound function* resets `this` to the global object, i.e `window` in case of a browser.

See this example:

(function () {
    alert("1: " + this); // this == myObject

    (function () {
        alert("2: " + this); // this == window
    })();

    (function () {
        alert("3: " + this); // this == myObject
    }).call(this);
}).call(myObject);

*) I.e. calling `func()` instead of `obj.func()`. `this` would become `obj` in the latter case.

First clarification:

In case of backbone.js the reason why they wrap their code in `(function () {...}).call(this)` is that this way you don't need to know the actual name of the global object (`global` in case of node.js).

See http://backbonejs.org/docs/backbone.html#section-4

Second clarification:

If the script is run by a browser, `this` is the same object as `window` if you are not in the call context of a bound function. In a standalone JS engine (node, rhino …) the global object is not named `window` but `global`.

The jQuery developers know you want to run their script in a browser, because you would have little fun with it if you don't have a document to manipulate in first place.

Backbone.js, like underscore.js, is general purpose so the developers do not know the name of the global object. And they don't care.

So when jQuery does

(function (window) {
    ...
})(window);

it could have been implemented this way too

(function () {
    var window = this;
    ...
}).call(window);

and because `this===window`

(function () {
    var window = this;
    ...
}).call(this);

Read the examples backwards to see what the backbone hackers did. (They call the global object `root`. You may want to read the annotated code.)

I for one would have chosen

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

but in the end it does not matter I guess.

Problem

Here is the Backbone wrapper ``` (function(){ // Backbone.js }).call(this); ``` For comparison. Here is the jQuery wrapper: ``` (function( window, undefined ) { // jQuery.js })( window ); ``` Regarding the BackBone Wrapper: I understand the need for a immediately invoked (via call) function expression - to provide privacy (encapsulation) I understand why it is an anonymous function - to reduce global symbols. However I don't understand what 'this' refers to? + Why the difference in wrappers? Reference MDN - this

Original source

Related problems