I am a little confused regarding closures in this example
function f(param){
var n=function(){ //n is assigned the function that returns param
return param;
};
param++; //increments 1 and n keeps a reference to the param
return n;
}
var inner=f(1);
inner();
I understand the concept of closures, I just dont understand how it works in this example.
Lets see in steps whats happening here:
you call function f with argument 1 and assign the result to variable inner.
When f(1) is called, the scope of f has 2 variables (param and n)
The variable params is the passed argument and n is a function.
So, inside function f -
variable n is initialized to a function, then param is incremented, then n is returned from the function f.
This returned function (n) is assigned to inner.
when inner is called, it returns param - which is in scope of function n due to closure.
Hope the steps were clear.
Now, you're doubt was how n got access to param++. It didn't, param++ was already executed when f(1) was called. All n has is just a reference to the value of param.
In param becomes a local variable to the function which is not same as the argument of the function f. The function f is returning n which is a function
function f(param) {
var n = function() { //n is assigned the function that returns param
return param;
};
param++; // here param become a local variable of the function f
return n;
}
var inner = f(1);
console.log(inner());
Here in this example, the local variable param ends up within a closure of that anonymous function. Here in this case, until the outer function returns, it can change the local execution context which will be used by the anonymous function whenever it gets executed.
Related
Javascript supports First Class Functions, in which case we can pass the function as an argument. An anonymous function that is defined inside an argument list of another function, what is the lexical environment (i.e scope) of that anonymous function?
for example:
var m = 2;
(function(p1,p2){
p2(p1);
})(true, function(p1){ // an anonymous function passed as an argument.
m = 3;
if(p1){...}
}); // the end of self-invoked function expression.
The function would have access to the scope where it was defined and include any parent scope (e.g. global/window). If defined inside of another function, it would have access to any variables defined within that function. If passed in as an argument like a callback, it wouldn't have access to variables defined within the function it was passed into because it was defined outside that function and passed in as an argument.
Example:
var a = 1;
(function(callback){ //func1
//access variable in parent scope
console.log('func1', a); //outputs 1
//define a new variable within this function's scope
var b = 2;
//call our callback
callback();
//define and call a function within this function's scope
(function(){ //func3
//access variable in parent scope
console.log('func3', a); //outputs 1
//access variable in parent function scope
console.log('func3', b); //outputs 2
})();
})(function(){ //func2
//access variable in parent scope
console.log('func2', a); //outputs 1
//access variable from invoking function
console.log('func2', b); //outputs undefined
});
This would output something like:
func1 1
func2 1
func2 undefined
func3 1
func3 2
Where all the functions can see variable a because it is in a parent scope to all functions. The argument function can't see variable b because b is defined in another function and the argument function was defined outside and passed in as an argument. And the function defined within the first function can see both a and b.
Calling an IIFE is effectively the same as first assigning the function to a variable, then then calling the function through that variable; as with any other use of anonymous functions, it's just a shortcut that avoids giving a name to the function. So:
(function(p1,p2){
p2(p1);
})(true, function(p1){ // an anonymous function passed as an argument.
m = 3;
if(p1){...}
});
is equivalent to:
var temp = function(p1,p2){
p2(p1);
};
temp(true, function(p1) {
m = 3;
if(p1){...}
});
except for the addition of temp to the outer scope; since this variable doesn't appear anywhere else, it has no effect. The scopes of all other variables are identical in the two scenarios.
When you're unsure what the scopes of a function defined in the arguments list of a call is, notice that
fn(function x(…) { … })
is equivalent to
_temp = function x(…) { … };
fn(_temp)
Arguments are evaluated before the actual call, and they're evaluated in the same scope as the call itself is evaluated in.
Can someone explain why in the following function, I am able to pass an argument to a nested function? My understanding is that it has to do something with closures and scope(which I thought I had a decent understanding of), but I can seem to follow how exactly this argument is being passed.
The below function outputs 1,2 respectively. But how is the return statement doThis() getting the argument/parameter for "a"? I cant figure where/how this is accessed/passed.
function doSomething(){
var b = 1;
return function doThis(a){
console.log(b);//1
console.log(a);//2
}
}
var exec = doSomething();
exec(2);
The function doSomething() returns another function so when you execute
var exec = doSomething();
You can think of that exec as containing the following function
function doThis(a){ // <- takes an argument
console.log(1); // comes from the b argument in the outer scope
console.log(a); // not set yet
}
Thus when you call exec(2) you are actually calling doThis() with an argument 2 which becomes the value of a.
This is a slightly simplified version. To expand on that, the doSomething() function is described as closing over doThis() creating a closure. Conversely, the function doThis() is closed over or inside a closure. The closure itself is simply a limited state around the function:
function doSomething(){ // --> defines the closure
var b = 1; // variable only visible within doSomething()
return function doThis(a){ //<--> function has access to everything in doSomething(). Also defines another closure
console.log(b); // --> accesses the OUTER scope
console.log(a); // <-- comes from the INNER scope
} // <-- end INNER scope
} // --> end OUTER scope
When you execute doSomething() the returned result still retains access to the scope within it, this is why doThis() has access to the value b - it's simply reachable for it. It's similar how you can do
var foo = 40;
function bar(value) {
return foo + value;
}
console.log(bar(2));
Only in this instance any other code will have acces to foo as it's a global variable, so if you do foo = 100 in a different function, that will change the output of bar(). A closure prevents the code inside from being reachable from outside the closure.
When you assign var exec = doSomething();, exec is basically writing:
var doSomething = function(a) {
console.log(b);
console.log(a);
}
It became its own function. So passing in 2 like so exec(2) works like any normal function except that it has the variable b available to it because of the closure.
Hope somebody finds the time to explain little about functions in functions and scoping.
I am trying to understand little more on functions and scope of variables and found a quite good tutorial, but this part I just do not get.
The task:
Create a function sum that will work like that: sum(a)(b) = a+b and accepts any number of brackets. Examples:
sum(1)(2) == 3
sum(5)(-1)(2) == 6
The solution:
function sum(a) {
var sum = a;
function f(b){
sum += b;
return f;
}
f.toString = function() { return sum };
return f; //line 12
}
alert( sum(1)(2) ); // 3e
The Explanation:
To make sum(1) callable as sum(1)(2), it must return a function.
The function can be either called or converted to a number with valueOf.
The solution is really self-explanatory:
My interpretation:
This f in function f(b) returned to the scope, which is from line 02 - 12.
The f in f.toString, is the currently returned f from function(b)
The next return f returns to the scope which is outside the function sum(a).
Problem:
I cannot figure out, where I need to think differently, because like I described above, the function would not be called again, so where is the part of the code, that make the 'several parentheses' possible?
Moreover, did I correctly assume where the fs are returned? Would be great if somebody would give some explanations.
The function sum returns a function, which we refer to as f.
The function f also returns a function: in fact, the function f returns itself.
When the function f is defined inside of sum, it gets permanent access to all variables currently visible in the scope chain. Here, it includes the locally-defined variable sum (the local running sum tally) and f (the function itself). (A "closure" is what we call the functional code of f along with all its in-scope variables.)
Because f returns itself, you can chain f with repeated calls:
var this_is_f = sum(1);
var same_f_again = this_is_f(2);
var f_a_third_time = same_f_again(3);
Or simply:
sum(1)(2)(3);
It is important to note that in my first example, I don't create new functions; instead, I just refer to the exact same function object with three different identifiers.
Each call to sum creates a brand-new f with a new local sum in its scope (here, I mean the local sum defined on the first line of the function named sum). However, calling the function sum does not clobber any old f, because each call to sum instantiates a new f (and knows nothing about any other fs that have been created on prior calls to sum). That way, you can have multiple tallies running:
var first_tally = sum(1)(2); // first: 3
var second tally = sum(4)(5); // second: 9
first_tally(3); // first: 6
second_tally(6); // second: 15
The reason you're able to see a meaningful result at any time is that f stingifies to the value of sum, instead of showing you its source code.
If you take this code and simplify it to the bare minimum I would be easier to understand. Take a function add that sums only 2 numbers:
function add(x,y) {
return x + y;
}
The above is a "normal" function. If you don't pass all the arguments you'll get unexpected results.
Now, if you want a function that adds 2 to any number, you could partially apply an argument to add, for example:
function add2(x) {
return add(2, x);
}
But in JavaScript we have first class functions (objects that can be passed around), so a function can take functions as inputs and return other functions. This is where "currying" comes in handy. While "partial application" lets you fix function arguments, "currying" takes a function of many arguments and breaks it down into a function of a single argument that returns another function of one single argument until all the arguments have been evaluated, in order, and then returns the result. For example:
function add(x) {
return function(y) {
return x + y;
}
}
Now you can create a function add2 by currying the function add:
var add2 = add(2);
add2(1); //=> 3
The normal function and the curried one have equivalent computations where:
add(1, 2) === add(1)(2)
This is what makes "several parentheses" possible.
In JavaScript "scope" and "closure" refer to functions but they're different concepts. A "scope" determines the reach/privacy of your variables while a "closure" lets you encapsulate code and carry it around. In the curried function above the variable x is kept in memory through closure because it's referenced inside the returned function object.
A particular limitation of "currying" is that you can't have functions of dynamic arity; the number of arguments must be fixed. This is not the case in the code you post where your sum function must be able to add a new number to the previous sum indefinitely.
Similarly to "currying" there's the idea of "generators"; a pattern to model sequences of lazy computation, in this case just adding a number to the previous sum on demand.
function sum(a) { // begin closure
var sum = a; // kept in memory...
function f(b) {
sum += b; //...because you use it here
return f;
}
f.toString = function() { return sum };
return f;
} // end closure
A different (maybe more clear) way to express your code would be to return an object to chain the computations, where you can either add a new number to the previous sum, or get the total sum so far:
function add(a) {
var sum = a;
return {
plus: function(b) {
sum += b;
return this;
},
sum: function() {
return sum;
}
}
}
add(1).plus(2).plus(3).sum(); //=> 6
In your code the returned function f acts as plus and toString as sum which retrieves the value.
Line 01-13 defines the function sum within the global scope.
Line 15 calls sum and changes scope to inside the function.
The variables a and sum and the closure function f are all defined in the function's scope - with the sum variable hiding the function definition from the global scope.
I'll skip over the toString bit here as its not important till later (when it gets very important).
The function sum finally returns a reference to the closure function f to the global scope as an anonymous function (since f can only be referenced by name from within its containing function's scope).
Back to line 15 - sum(1)(2) is the same as (sum(1))(2) and since sum(1) returns f then this can be reduced to (f)(2) or, more simply, f(2).
Calling f(2) adds 2 to sum - sum is defined in two scopes: as a function in the global scope; and as a variable (currently assigned the value of 1) within that function which hides the definition from the global scope - so, in f, the sum variable is set to 1+2=3.
Finally, in f, the function returns itself.
Back, again, to line 15 - f(2) returns f (although the named function f cannot be referenced in the global scope and, again , is treated as an anonymous function)
alert() is processed and the anonymous function (referred to as f) is converted to a string to be alerted; normally when alert() is called on a function it will display the source for the function (try commenting out Line 10 to see this). However, since f has a toString method (Line 10) then this is invoked and the value of sum (as defined in the function containing f) is returned and 3 is alerted.
Let's step through the function line by line:
function sum(a) {
This part is pretty self-explanatory; we have a function named sum which accepts an argument a.
var sum = a
Here we have a local variable called sum that is set to the value of the argument that is passed in.
function f(b) {
sum += b
return f
}
This is an inner function called f that accepts an argument called b. This b is then added to the value of sum from the outer scope (i.e., inside the scope of the function that is also called sum). After that, the function returns itself.
f.toString = function() { return sum }
This is the fun part! When you normally console.log a function, it will just spit out the function's source. Here we are redefining the toString method to instead be a function that spits out the value of sum. This is why you end up seeing the running total that is displayed instead of the function's source even though what you are returning is still a function.
Finally we have:
return f
So you basically have a function sum, returning a function that returns itself. The function sum basically sets everything up, but after calling sum(3), you then work with f, which you repeatedly call.
So the first time you call sum, you essentially get back this function:
function f(b) {
sum += b; //value of sum is 3
return f;
}
In this context, the value of sum will be the value of a that you passed into the initial call of the function sum. However, since the toString of f has been redefined, you only see the value 3. Then let's say you do sum(3)(4).
You get back, as before:
function f(b) {
sum += b; //value of sum is 3
return f;
}
But then you are actually calling f with an argument of 4 (basically f(4)). Since f is an inner function, it has full access to the scope of its parent function. This parent function (sum) is maintaining the the running total in a variable called sum, which is accessible to f. So when you now call f(4), you have b set to 4 and sum having a value of 3:
function f(b) { //b is 4
sum += b; //value of sum is 3 + 4, which is 7
return f;
}
So with each subsequent pair parentheses you are making repeated calls to the same f which is maintaining a running tally.
Another way is to think of sum as a kind of factory that can give you different f's, all of which keep their own running tallies (basically behaving like accumulators):
var firstSum = sum(4);
var secondSum = sum(2);
firstSum(5); //equivalent to sum(4)(5) returns 9
secondSum(2); //equivalent to sum(2)(2) returns 4
There are 3 concepts being played here
closures (no scope).
functions are first class OBJECTS in javascript (allows for chaining f(a)(b)(c)). There's no need to save a handle to the function to call it later.
I'll give you a run-down and then add some extra explanations afterwards
function sum(a) {
// when sum is called, sumHolder is created
var sumHolder = a;
// the function f is created and holds sumHolder (a closure on the parent environment)
function f(b) {
// do the addition
sumHolder += b;
// return a FUNCTION
return f;
}
// change the functions default toString method (another closure)
f.toString = function() {return sumHolder;}
// return a FUNCTION
return f
}
/*
* ok let's explain this piece by piece
*
* you call sum with a parameter
* - parameter is saved into sumHolder
* - a function is returned
*
* you call the returned function f with another parameter
* EXPLANATION: { sum(a) } returns f, so let's call f as this => {...}()
* - this private (priviledged) function adds whatever it's been passed
* - returns itself for re-execution, like a chain
*
* when it all ends {{{{}(a)}(b)}(c)} the remainder is a FUNCTION OBJECT
* this remainder is special in that it's toString() method has been changed
* so we can attempt to cast (juggle) it to string for (loose) comparison
*
*/
The concept behind closures is quite easy to understand but it's application make's your head spin until you get used to the idea that there is no function scope in javascript, there is closures and these are powerfull critters indeed
// this anonymous function has access to the global environment and window object
(function()
{// start this context
var manyVars, anotherFunc;
function someFunc() {
// has access to manyVars and anotherFunc
// creates its own context
};
anotherFunc = function () {
// has access to the same ENVIRONMENT
// creates its own context
};
}// whatever is in these keys is context that is not destroyed and
// will exist within other functions declared inside
// those functions have closure on their parent's environment
// and each one generates a new context
)();
Functions are first class objects. What does this mean? I'm not sure myself but let me explain with some further examples:
// how about calling an anonymous function just as its created
// *cant do the next line due to a language constraint
// function(){}()
// how about a set of parens, this way the word "function" is not the first expression
(function(){}());
// the function was created, called and forgotten
// but the closure inside MAY STILL EXIST
function whatDoIReturn() {
return function (){alert('this is legal');return 'somevalue';}();// and executed
}// returns 'somevalue'
Don't take this word for word. Go look for other people's code, check the Crockford and ask any and all questions that come up
Crockford had this example to keep myArray from being in 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 don't get why it isn't
var myName = (function(X) {
Q: When I call myName(3), isn't "var myArray=" executed a 2nd time?
Suppose it's not executed a 2nd time because JavaScript knows that it's already been defined... What about a loop or some other logic between the var stmt and the return function stmt? Wouldn't it be executed every time?
Q: Can you name the subfunction and call it instead of calling myName?
okay, let's break this down...
var myName = (function(){
...
}());
that piece sets myName to whatever that anonymous function returns, so if it were:
var myName = (function(){ return 42; }());
myName would equal 42. If that doesn't make sense, this is the same thing:
function someFunction(){ return 42; }
var myName = someFunction();
So in your example, myName is set to function(X){ return myArray[X] }. So myName is a function. When you call it, the only code that is run is return myArray[x]. myArray is kept in what is called a closure, it is only exposed to the myName function and the anonymous one surrounding it.
I wrote an article on closures years back that may help you: http://www.htmlgoodies.com/primers/jsp/article.php/3606701/Javascript-Basics-Part-9.htm (scroll down to the "Closures" header).
OK here it goes ..
answer to Q1 . it is not myName = (function(x) because the part inside the brackets returns a function which takes X . i.e. myname is not assigned to (function(){}) but to the return value of it .
Q2. No when u calll myName 2nd time it already points to the inner function hence the outer function is not invoked at all .(this is the sepciality of closures where the value stays alive in inner function even if outer functions are completed.)
Q3. Well nopes we can name the inner function but the name will be valid only inside the outer function and since outer function has completed the name would be useless.
The outer function doesn't have to have an argument X, because it's only purpose is to return another function (which then is parametrized). Thus no argument is needed here.
Thus the only effect is to bind the function(X)... thing to the variable myName. Therefore no other constructs like loops or so does make sense here.
Q1+2: Note the () right of the comment "This function is invoked immediately". The outer function defined is not stored in myName, but immediatly called. Itself then returns an anonymous function which has no name and requires a single parameter (X). This function beeing returned is stored in myName.
To grasp closure you should start thinking about functions just as another value of a variable which can be stored and returned jsut as any other value.
Q3: myName is the subfunction.
Okay answer in turn:
First, why it's var myName = (function() { and not var myName = (function(x) {
In this case because the x value isn't required to create the function you are returning. The data structure of the array contained in the returned function is hard coded and so you don't need additional information to construct it. Much in the same way that
function a() {
return 1 + 2;
}
Doesn't have any arguments, because it's values are hardcoded. This is an example of functions as data or first class functions
Question two: is var myArray executed every time.
The short of it is no. myArray has been assigned to at this point so it has a value that the system has already calculated. In this case it's a function. The myArray potion has been set and so there is no cause to keep executing it. If the outer function didn't return a new function then yes it would need to get called again and again but that would defeat the purpose of this abstraction.
Question three: can you call the inner function.
No, it's out of scope. The entire point of this example is that you have defined a function generator.
Answer to first question:
no, the first "line" is returning a function so when you call "myName" you are actually executing the returned function
function(X) {
return myArray[X];
}
Answer to second question
no, such a function can still refer to the array "myArray"... in fact the purpose of this closure is to make myArray available in the global scope
In words:
myName is the result of an immediately executed anonymous function. It returns a function reference (to an anonymous function). That function has one parameter: X. After execution of the topmost anonymous function, myName is a reference to the inner anonymous function.
Now the inner anonymous function has access to myArray via a closure (myArray and the returned anonymous function both live within the scope of the topmost anonymous function). So if you execute myName, you actually execute the inner anonymous function, which can access myArray.
The topmost anonymous function is executed immediately and once (it returns a reference to the inner function). So myArray is declared within that execution context, and only once.
Since the definition of the myName object (function) ends in '()', its function is called immediately, returning a new function which has the myArray variable statically bound to it. myName is then accessible globally but myArray is not as it is within a function closure. When you reference myName() it has exclusive access to the bound array.
This approach ensures that myArray is only allocated once, when the outer function 'is invoked immediately'. After it is invoked, myArray isn't in the global scope, but is still available to the anonymous inner function.
The approach you proposed would work, but would require that the array be allocated each time the function was called. (Or be allocated outside the function, in the global scope.)
Take below code iterates over 6 input buttons and attaches an onclick event to every button that alerts the index number of the respective iteration:
for (var i = 1; i < 6; ++i) {
var but = document.getElementById('b_' + i);
(function (el) {
var num = i;
but.onclick = function () {
alert(num);
};
})(but);
}
As you can see, in each iteration there is a self-invoking function that creates a scope to store the iteration index in that scope.
I have always used this type of pattern to attach an event that is dependant on a variable that is changed during iterations.
Can anyone explain to me exactly why the above works, and how the num variable is captured in the scope?
Also, is the self-invoking function used above called a closure ?
Yes this is a closure.
Everytime a function is executed a new object is created to hold (as its properties) the variables that are declared with var and every function declared inside it. This object is called the execution context (or sometimes the scope object).
Everytime a function is declared (or defined in an expression) the new function has attached to it the execution context object that is current. This creates what is known as a scope chain.
When executing code needs to resolve an identifier to a value it first looks for it in the properties of the current execution context. If the identifier is not found it uses the exection context object attached to the function that is being executed. It keeps going up the scope chain until it reaches the global level.
In your example each time "self-invoking function" gets executed a new execution context object is create holding the properies el and num. Since the function assigned to onclick is created inside this execution context you will get a new instance of this function each time. These instances will each have the corresponding execution context object attached. Hence the first will have the execution context when num has been assigned 1, the second will have the execution context where num has been assigned 2 and so on.
When each of the onclick functions run the code will initially look for the identifier num in the current execution context. However this inner function doesn't var a num so its not found. So Javascript looks to the execution context attached to the function when it was created. Here it will find num, the num will contain the value assigned to it during that iteration as described above.
Hey guys. Yep it is a closure. If you want to know what exactly occurs when function is creating then study following article.
http://www.jibbering.com/faq/faq_notes/closures.html
Wouldn't that mean that the var i defined outside the closure is a global variable, thus giving the self-invoking function access to it?
Each time through the loop, evaluating function (el) {...} creates a new anonymous function, which is immediately invoked. Within the anonymous function, a variable named num is created (because JS doesn't do static variables, it's a new one each time). num is assigned the value of i when the function is invoked (which is immediately). This gives us 6 anonymous functions and 6 nums, each holding the values 1 through 6.
With each invocation of the anonymous function, an inner anonymous function is created and stored as the click handler. The inner function references a num. As a result, a closure is created which ensure that when the outer function exits, num isn't destroyed. Should the inner function ever be discarded, num will soon follow.
for (var i = 1; i < 6; ++i) {
var but = document.getElementById('b_' + i);
(function (el) {
var num = i;
but.onclick = function () {
alert(num);
};
})(but);
}
Now lets start the execution of the loop
initially i=1,but= domelement with id ='b1'
now comes the function invoke,
ok it calls the inner function(with parameter el) with value of parameter of but('b1')
and starts executing it that is what invoking actually means execute it now.
Now inside it ,
new instance of num is assigned 1
but.onclick is assigned a function so stores function in memory also sees that it accesses num so num is now closed variable that means its lifetime is increased so as to be accessed by onclick function when invoked.
Next iterationnow value of i=2,but= domelement with id ='b2'
now comes the function invoke,
it calls the inner function(with parameter el) with value of parameter of but(value='b2') .
Now inside it ,
new instance of num is assigned 2
but.onclick is assigned a function so stores function in memory also sees that it accesses num so num is now closed variable that means its lifetime is increased so as to be accessed by onclick function when invoked.
Similary all others are exectuted till the loop terminates.