I do not understand this closure example

Crockford had this example so that myArray does not fall into the global scope:

var myName = (function() { var myArray = ['zero','one','two','three','four']; return function(X) { return myArray[X]; } }()); // This function is invoked immediately result = myName(3); // Now invoke it "for real" 

Q: I do not understand why it is not

 var myName = (function(X) { 

Q: When I call myName (3), does "var myArray =" run the 2nd time? Suppose it is not executed a second time because JavaScript knows that it is already defined ... What about a loop or some other logic between var stmt and the return function stmt? Won't this be done every time?

Q: Can you name a subfunction and call it instead of calling myName?

+6
source share
9 answers

ok, let it break ...

 var myName = (function(){ ... }()); 

this part sets myName to what the anonymous function returns, so if it were:

 var myName = (function(){ return 42; }()); 

myName will be 42 . If that doesn't make sense, it's the same thing:

 function someFunction(){ return 42; } var myName = someFunction(); 

So, in your example, myName set to function(X){ return myArray[X] } . So myName is . When you call it, only the following code is executed: return myArray[x] . myArray is stored in a so-called closure; it is available only for the myName function and anonymous environment.

I wrote an article about closing years ago that might help you: http://www.htmlgoodies.com/primers/jsp/article.php/3606701/Javascript-Basics-Part-9.htm (scroll down to the "Closing" heading )

+5
source

Ok, here it is. answer to Q1. it is not myName = (function (x), because the part inside the brackets returns a function that takes X. ie myname is not assigned (function () {}), but returns its value.

Q2. No, when u calll myName the 2nd time that it already points to an internal function, so the external function is not called at all (this depends on closing the closures when the value remains alive in the internal function, even if the external functions are completed.)

Q3. Well, we can call an internal function, but the name will be valid only inside the external function, and since the external function has completed this name, it will be useless.

+3
source

An external function should not have an argument X , because the only goal is to return another function (which is then parameterized). Thus, no arguments are required here.

So the only effect is to bind the function(X)... object to the myName variable. Therefore, no other constructions, such as loops, etc., make sense here.

+1
source

Q1 + 2: Pay attention to () right of the comment "This function is called immediately." A myName external function is not stored in myName , but is called immediately. Then it returns an anonymous function that has no name and requires one parameter ( X ). The returned function is returned in myName.

To capture a closure, you should start thinking about functions just like another variable value that can be saved and returned by jsut like any other value.

Q3: myName is a subfunction.

+1
source

Answer well in turn:

First, why is it var myName = (function() { rather than var myName = (function(x) {

In this case, since the value x not required to create the return function. The array data structure contained in the returned function is hard-coded, so you do not need additional information to create it. Just like

 function a() { return 1 + 2; } 

There are no arguments because the values ​​are hard-coded. This is an example of functions as data or first class functions.

Question two: var myArray is executed every time.

In short it is not. myArray was assigned at this point, so it has a value that the system has already calculated. In this case, it is a function. Miriam myArray is installed, so there is no reason to continue its execution. If the external function has not returned a new function, then yes, it will need to be called again and again, but this can defeat the purpose of this abstraction.

Question three: you can call an internal function.

No, that’s out of scope. The whole point of this example is that you have defined a function generator.

+1
source

The answer to the first question: no, the first "string" returns a function, so when you call "myName", you actually execute the returned function

 function(X) { return myArray[X]; } 

The answer to the second question

no, such a function can still reference the array "myArray" ... in fact, the purpose of this closure is to make myArray available in the global scope

+1
source

In words:

myName is the result of an immediately executed anonymous function. It returns a function reference (for an anonymous function). This function has one parameter: X After executing the topmost anonymous function, myName is a reference to an internal anonymous function.

Now the internal anonymous function has access to myArray through closure ( myArray , and the returned anonymous function lives within the topmost anonymous function). Therefore, if you execute myName , you are actually executing an internal anonymous function that can access myArray .

The topmost anonymous function is executed immediately and once (it returns a reference to an internal function). Therefore, myArray declared inside this execution context and only once.

+1
source

Since the definition of myName object (function) ends with '()', its function is called immediately, returning a new function that has the variable myArray statically bound to it. myName is then globally accessible, but myArray is not the same as in function closure. When you reference myName (), it has exclusive access to the associated array.

+1
source

This approach ensures that myArray is allocated only once when the external function is "called immediately". After it is called, myArray is not in the global scope, but is still available for an anonymous internal function.

Your approach will work, but will require that the array be assigned each time the function is called. (Or being highlighted outside a function in a global scope.)

0
source

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


All Articles