Understanding the code structure underscore.js

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

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

Can anyone explain what this template does? and what are the benefits of using it?

Why not just:

 (function() { // the library code }()); 
+6
source share
4 answers

Since both are equivalent in the usual context, I looked at the source and was changed from the form you offer to the current form 2 years ago, with the following comment:

"Added a clear definition of the global context of compatibility with Adobe JS"

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

The logs for the first version of Underscore with this change say: "Improved compatibility of the subtree with the Adobe JS engine, which can be used for script Illustrator, Photoshop and friends."

http://underscorejs.org/ Version 1.4.3

So, this change was made because the Adobe JavaScript engine did not match ES3 or ES5 at the time, but Underscore was compatible with this change.

If you do not plan to run your module in Adobe JS, you can use any of these forms. If you later, then Adobe JS requires the form used by Underscore.

+3
source

This is probably due to the noConflict function if you are using multiple underscore versions at the same time.

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

Alternatives may be:

 (function () { // library }(window)); // hard reference to window (not so nice) (function () { // library }({})); // this will break `noConflict` detection 
0
source

This will wrap all the code in an anonymous function. Thus, the variable declared inside the function will remain private, so other scripts will not be able to access your code.

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

In this case, regardless of the default value of this , the window object will be available inside the anonymouse function. Here is an example of this.

 (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 type of wrapper is typically generated in preprocessor languages ​​such as CoffeeScript.

0
source

The first part :

 var x = 1; // `x` is in the global scope (function() { var y = x; // `y` is in the current function scope }()); x = y; // Here `x` becomes `undefined` because `y` is not declared in this "outer" scope 

As for " why, " this is an easy way to avoid troubles (there are no "memory leaks" [all declared internal phenomena are not valid at the end of the function], no declaration conflicts, etc. ").

Second part : Regarding call (there also apply which is similar), it is just a matter of context.
The author wants the context of the anonymous function (this function above) to have its own this , pointing to the same this external area.

Hope this is clear :)

0
source

All Articles