Reputation:
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
Upvotes: 3
Views: 190
Reputation: 26043
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.
Upvotes: 6