Difference between the two types of JavaScript self-emitting function

I always use the following self-executing function to not expose my global scope code in JavaScript:

(function() { //Code comes here })(); 

I believe this is also called self, performing an anonymous function. Sometimes I also see the code below used for the same purpose:

 (function(d){ //Code comes here })(document.documentElement); 

I'm not sure what makes a difference here, so I ask this question.

What is the difference (or differences) between these two types of native JavaScript execution function?

+4
source share
6 answers

The code below demonstrates what happens. In fact, the variables foo and bar do not exist, and the functions are anonymous.

 var foo = function() {} foo(); var bar = function(d){} bar(document.documentElement); 

The (function(d){})(d) method is called closure . He used to transmit the values ​​of variables that can be changed, for example, in cycles.

Take a look at a practical example:

 for(var i=0; i<10; i++) { document.links[i].onclick = function(){ alert(i); //Will always alert 9 } } 

After implementing closure:

 for(var i=0; i<10; i++) { (function(i){ document.links[i].onclick = function(){ alert(i); //Will alert 0, 1, ... 9 } })(i); } 
+8
source

Remember that arguments and function variables are the same thing, deeply.

The second example (mostly) is simply shortened for

 (function(){ var d = document.documentElement; }()); 

as it avoids the need for var and = .

There are several common uses for this template:

  • Creating lexically restricted variables (just remembered it after watching Rob's answer ...)

     //this does not work because JS only has function scope. // The i is shared so all the onclicks log N instead of the correct values for(var i = 0; i< N; i++){ elems[i].onclick = function(){ console.log(i); } } //Each iteration now gets its own i variable in its own function // so things work fine. for(var i=0; i<N; i++){ (function(i){ elems[i].onclick = function{ console.log(i); }; }(i)); } 

    In this case, passing parameters directly allows us to reuse the same variable name inside , so that var i = i cannot. Also, brevity is an advantage because it is just a template template that we don’t want to dominate the important code around it.

  • This makes it easy to convert old code without having to think too much about it.

     (function($){ //lots of code that expected $ to be a global... }(jQuery)) //and now we can seamlessly do $=jQuery instead. 
  • Parameters that are not passed are set to undefined . This is useful because usually undefined is just a global variable that can be set to different values ​​(this is especially important if you are writing a library that should work with arbitrary third-party scripts)

     (function(undefined){ //... }()) 
+3
source

The first function does not accept any parameters. The second takes one parameter. Inside the function, parameter d . d set when document.documentElement when the function is called.

0
source

It seems that the author of the second code wants to use d as a shorter way to write document.documentElement inside a function.

0
source

One of the reasons for using the second form with an argument is that it isolates your code from other js code loaded later on the page (for example, other libraries or structure code), which can override the variable passed as an argument.

One common example: if the code in your self-tuning anonymous function depends on jQuery and wants to use the $ variable.

Other js frames also define the $ variable. If you code your function as:

 (function($){ //Code comes here })(jQuery); 

Then you can safely use $ for jQuery, even if you load another library that defines $.

I saw that it was used defensively with people passing in all the "global" variables that they needed inside their block, such as window, document, jQuery / $, etc.

Better safe than sorry, especially if you use many third-party widgets and plugins.

Update:
As others have pointed out, the circle of parentheses around a function is a closure. They are not strictly necessary many times when this template is used (@Rob W gives a good example where they are needed), but they say that you have a very long function body ... the outer parentheses tell others reading the code which the function is, probably executed independently.

The best explanation I've seen in this example is in the video of Paul of Ireland: http://paulirish.com/2010/10-things-i-learned-from-the-jquery-source/ , starting at about 1:30

This SO question also contains some informative answers: How do you explain this structure in JavaScript?

0
source

if you want to pass arguments to autonomous executing anonymous functions, use the second. This can come in handy when you want to use variables in functions that have the same name with others in the global scope:

 var a = "I'm outside the function scope", b = 13; alert(a); alert(b); (function(a,b){ // a is different from the initial a alert(a); // same goes for b alert(b); })("I'm inside the function scope",Math.PI); 

It is also useful to use something like:

 var a; console.log(a === undefined); // true undefined = true; console.log(a === undefined); // false (function(undefined){ console.log(a === undefined); // true, no matter what value the variable "undefined" has assigned in the global scope })(); 

when trying to implement a null object design template

If you are concerned about efficiency, you can use something like this:

 var a = 2; (function(window){ alert(a); // accessing a from the global scope gets translated // to something like window.a, which is faster in this particular case // because we have the window object in the function scope })(window); 
0
source

Source: https://habr.com/ru/post/1384601/


All Articles