I've been trying to wrap my head around scope, specially closures.
I know that there are many posts about the topic, and I've been reading a lot. But most places refer to the topic as advanced, and use terminology that is relatively difficult to grasp. I would like to be absolutely sure that I've got the basics right, so that I don't go venture into the more intricate topics with a wrong idea of how functions really work.
So... I picked a basic function, and would really like for someone to tell me if what I think its happening under the hood is what is actually happening.
This is the code:
function sum(a) {
return function(b) {
return a+b
}
}
console.log( sum(1)(sum(2)))
(I know that it's not actually do the sum, I was tweaked with it, to try to understand what was going on in each step.)
So, my main doubt was why A was 1, and not 2. I reached the conclusion that the closure is created, as soon as function(b)is created to take sum(2) as an argument, right after being returned by sum(1). Therefore, by the definition of closure, I'm assuming that at the time the function is created it also saves the lexical environment (in which a = 1). Is this right?
I've made a diagram of the steps.
here is what happening
1) If a function returns a function and that returned function gets called immediately that's called currying (A functional programming term). You have mixed currying and closure both concept in this example.
2) First your sum(1) part gets called . which will return function(b) {return a+b} (lets refer it as #1st) , but with It will keep alive a as 1 for the for the context of #1st only.
3) As the functions argument is a function call itself then that argument part will get called . e.g sum(1)(sum(2)) , here sum(2) part will get called and it returns function(b) {return a+b} (lets refer it as #2nd), also It will keep alive a as 2 for the context of #2nd only (closure).
4) Now we are immediately invoking #1st with #2nd as parameter with that currying syntax - #1st(#2nd)
5) so our a is unallocated variable and have value 1, b variable has a value function(b) {return a+b} . As we are concatenating these two, so final output is 1function(b) {return a+b}
N.B. - a) In case you wanted a sum of a+b and not that weird output just change your final line as console.log(sum(1)(2)) . b) In case you noticed closure a having value of 2 in the function referred as #2nd is never getting used anywhere but alive .
Whatever facility we use to transport an inner function outside of its lexical scope, it will maintain a scope reference to where it was originally declared, and wherever we execute it, that closure will be exercised.
In the next function you will see how the greet will use a variable salute declared inside the greeting function even when this is no longer being called, this is called a Closure.
function greeting(name) {
var salute = "Hello "; // This is a closure
return function() {
console.log(salute + name);
}
}
var greet = greeting("Dave");
greet(); // Hello Dave
You can learn a lot more about closures in the Kyle Simpson's book series You Don't Know JS but for this particular topic check You Don't Know JS: Scope & Closures. He uses a simple and up to the point language to explain difficult concepts like this one.
When sum is called it creates a scope. Within this scope there's the formal parameter a and an inner, anonymous function, which is immediately returned. This anonymous function is a closure, because it captures the scope of its enclosing function (sum). Consequently this inner function has access to a.
Now we come to the point that confuses you apparently: The inner function gets only a copy of sum's scope, not a reference to the original one. That means if we return from sum and thus eliminate its scope, this copy remains unaffected (a of the inner function remains 1). Further function calls of sum with different arguments don't affect the closure either.
Conclusion: A closure can exist longer than its enclosing function.
Technically speaking a of sum is stored in the stack, whereas the captured a of the closure is stored in the heap and is thus independent of the lifetime of sum.
By the way, what you're doing here is called currying. Instead of calling sum with several arguments you call it procedurally, with a single argument per invocation:
sum(1, 2); // multi argument form
sum(1)(2); // curry form
Related
I understand recursion in terms of how code is executed and why you might need it. What I am wondering about is that is it possible that function can reference itself within itself?
Given the following example:
function factorial(num) {
if(num ===0) {
return 1
}
return (num * factorial(num - 1));
}
factorial(2)
I want to understand what is happening under the hood in terms of how variables are stored in memory and how they're called and why is it possible to reference factorial inside a factorial function.
The way I understand how it is going to be executed at the moment:
Declare a function factorial on the stack that will reference an object on the heap. At this moment factorial still points to nowhere
Create an object on the heap(function) that will calculate factorial
Call factorial(2) which will take the reference on the stack where factorial points to, find the function on the heap and call it.
What I don't understand is that how when factorial is called, will it know what is factorial and where to find it? Is it related to closures somehow?
Another example(jest)
const someFunction = jest.fn((value) => {
expect(someFunction).toHaveBeenCalled()
})
Why I can reference someFunction inside the someFunction, as mentioned I suspect it is related to memory and how variables are stored, but I don't grasp the concept fully.,
By using a named function declaration/expression, the call checks the inner scope of the function and if it is not inside, it check the name of the called function and then the outer scope.
However, a name can be provided with a function expression. Providing a name allows the function to refer to itself, and also makes it easier to identify the function in a debugger's stack traces
By using arrow functions, the name of function is not set and does not remain by renaming as opposite of a named function declaration, where the name is always callable from the inner scope.
The Function Guide of the MDN Web Docs contains the information you seek. There are multiple ways you can reference a function from inside its body. It boils down to the fact, that
a function can access all variables and functions defined inside the scope in which it is defined
You can read this as a function can access everything defined in the scope in which it was defined. This includes itself.
I am doing the Udemy course Javascript: Understanding the Weird Parts right now, and I just learned about the creation phase and the execution phase that occurs when the interpreter interprets the JS.
I have a question, but I will first show you the code I am playing with:
http://codepen.io/rsf/pen/bEgpNY
b();
function b () {
console.log(a);
}
var a = 'peas';
b();
If I understand correctly, in the creation phase, the variables and functions are 'set', meaning they are given spots in memory. The variables are all given the placeholder value of undefined. Then in the execution phase, the engine executes the lines starting at the top. When b() is first called, 'a' still has the placeholder value of undefined, then 'a' is given its initial value of 'peas', b() is called again and this time 'a' has the value of 'peas'.
In my mind, one of two things has to be happening here. Alternative 1: In the creation phase, all variables are set before functions. This means that when a memory space for the function b() is created, the function includes a's value of undefined (because the 'a' memory space was already created with the value of 'undefined'). Alternative 2: the functions and variables are set in the lexical order they are in (in this case, b is created before a), and when b is created, the 'a' reference somehow means that the function is listening for any possible creation of an 'a' memory location, and when later the 'a' location is actually created, the reference refers to that spot.
Am I on the right track with either of these scenarios?
You can think of it like this.
Your original code:
b();
function b () {
console.log(a);
}
var a = 'peas';
b();
is actually executed like this:
var a;
function b () {
console.log(a);
}
b(); // log undefined because a doesn't have a value yet
a = 'peas';
b(); // log peas because a has a value
Basically all the variable and function definitions are hoisted at the top of the enclosing scope.
The order doesn't really matter because the code inside the b function doesn't get executed until you actually call the function.
If I understand correctly, in the creation phase, the variables and functions are 'set', meaning they are given spots in memory.
I would not use the term set for this--it usually is used to refer to a variable being set to (assigned) a particular value. I also would not use the term "spot" or "memory"--we don't need to worry about these internals. It's clearer just to say declared.
I also don't really like the use of the term "creation phase", which is both non-standard and confusing--what is being created, exactly? I would prefer the term "compilation".
The variables are all given the placeholder value of undefined.
To be precise, I would not say they "have the value of undefined", but rather "have no value", or "are not defined". undefined is not a value held by a variable which has not been assigned to yet; rather it's a state, which causes the variable to evaluate to the undefined value when accessed.
Alternative 1: In the creation phase, all variables are set before functions.
Yes, although again it's going to be confusing to use the word "set". Say, "all variables are declared before functions". This is the process of hoisting.
Alternative 2: the functions and variables are set in the lexical order they are in (in this case, b is created before a), and when b is created, the 'a' reference somehow means that the function is listening for any possible creation of an 'a' memory location, and when later the 'a' location is actually created, the reference refers to that spot.
No. The function does not "listen" to anything. It just executes when you tell it to.
Is this important?
Not really. It falls into the category of arcana. So we clog up our brains with rules like, variables hoist this way, function declarations hoist some other way, let has yet some other hoisting behavior. In practice, almost all style guides will call for you to declare variables at the top of the function, and linters will warn you if you don't (or can be configured to do so). This immediately eliminates all variable hoisting issues.
Some people like to put internal functions at the bottom of their function, and that works fine since, if it's a function declaration (ie function foo() { }) the whole thing (including the definition) is hoisted. If it's a function expression being assigned to a variable (ie var foo = function() { }), then it's a variable, and we already decided to put those at the top of our function--see paragraph above.
In general, if your program depends on hoisting behavior, it's written badly. If you need to understand hoisting behavior to understand how the program works, it's written badly.
To summarize, all you really need to learn is one rule: put variable declarations (and their initializations) at the top of your function. Then you don't have to worry about hoisting at all.
(There are some exceptions, such as declaring a variable inside a for statement, as in for (var i...), which is fine, assuming i is not being used for anything other than the index of the loop.)
For some reason, people learning JS seem sometimes to focus on these oddities--such as "why does " " == false or something. I would suggest instead focusing on the how to think about your problems, and break them down, and writing nice clean code that just works, and that you and other people can maintain without worrying about the arcana. I've been writing JS for many years, and cannot remember the last time I encountered a problem related to hoisting.
This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 9 years ago.
Code gives me:
A
B
C
When I click on A B C it always shows me the last one "vodka".
I want "martin" (for A), "lindsay"(for B), "vodka" (for C)
Please help me on my example.
myArray = [
{
letter: "A",
brand: "martin"
},
{
letter: "B",
brand: "lindsay"
},
{
letter: "C",
brand: "vodka"
}
];
var list = '';
for (var i = 0; i < myArray.length; i++) {
list += "<br>" + myArray[i].letter;
new_info = myArray[i].link;
(function(new_info) {
$(this).click(function(){ //this - refers to A or B or C
$('#box2').text(new_info);
});
}).call(this, myArray[i])
}
$('#box1').append(list);
Edit:
I said I wasn't going to write your code for you... well, I did: this fiddle does exactly what you're looking for. I solved the issue with context (this), closure issues and implied globals. It still needs a lot of work, but the fiddle shows what everybody has been saying: $(this) does not, cannot and will never point to a string constant like "A", or "B".
Sorry to say this, but your code is full of problems, but I will address the specific issue you're asking about here.
Inside the loop, you're assigning a click handler that, basically looks like this:
function()
{
$('#box2').text(new_info);
}
Where new_info is a variable that is declared in a higher scope. So far, so good. The problem is, the function object you're creating doesn't have its own copy of whatever value that variable (new_info) happened to hold when that function was created. Instead, the function references that variable. So when any of those functions is invoked it $('#box2').text(new_info) will be resolved to $('#box2').text("whatever value new_info holds when function is called"), not $('#box2').text("whatever value new_info was holding when function was created"). You can give each callback access to a copy by simply adding a second function to your code:
$(this).click((function(currentNewInfo)
{
return function()
{
$('#box2').text(currentNewInfo);
}
}(new_info)));
What I'm doing here is creating a function, that takes an argument, and calling it immediately. I pass new_info as an argument, so the value of currentNewInfo will be what new_info holds at that time (aka a copy)
The function I called (IIFE - or Immediately Invoked Function Expression) returns the actual callback. In this callback, I don't reference new_info, but the argument of the IIFE: currentNewInfo.
Because each function has its own scope, that variable is enclosed (hence the name closure), and cannot be accessed or altered from outside. The only thing that can still access the currentNewInfo variable is the function the IIFE returned.
Perhaps you are worried about name-conflicts (each callback you create uses references currentNewInfo), but that's not the case: each callback was created by a separate function, and therefore has access to a different scope. It's not possible to have a name conflict between scopes that don't access each other... Just to make things really simple to understand:
Where /\ and /\
|| ||
is return function() is scope of IIFE
So closures have access to a function's scope after it returns. That scope has precedence when it comes to resolving an expression to a value. To understand this better, here's a similar diagram to show you how JS resolves expressions:
Where each pink "outer environment record" is a scope of a function (closure scope of a function that has returned already or function currently being called). The last environment will either be the global object, or null (in strict mode). That's all there is to it.
Honestly, closures are tricky to get your head round at first, but once you grasp what I tried to explain here, they're great fun.
Check this link I can go on to explain the use cases and benefits and ways nested closures work, but I'd end up writing a book. The link I posted does a great job at explaining how closures work using rather silly drawings. It may seem childish, but they actually helped me a lot when I was trying to grasp the concept of lambda functions, closures and scopes out-living a function-call. The diagrams above are taken from the page I linked to, which explains the concepts a bit more in-depth, but I still think the simple, crude drawings are pretty self explanatory.
Other issues:
As someone pointed out: "What are you expecting this to reference". Looking at the snippet, this will just reference the global object (window), attaching the same/similar event handler to window simply doesn't make sense if you ask me.
Global variables are evil, implied globals even more so. I can't see new_info, nor myArray being declared anywhere. The way JS resolves expressions is a tad unfortunate and falls back to creating global variables, without so much as a peep:
var bar = 666;//global, always evil
function createGlobal()
{
var local = 2;
foo = bar * local;
}
createGlobal();
Let's look at foo:
JS is in createGlobal scope: var local is declared, and assigned 2.
foo is used, and assigned bar*local
|| || \\=>found in current scope, resolves to 2
|| ||
|| \\=>found in global scope, resolves to 666
||
||
||=> JS looks for foo declaration in function scope first, not found
||
||=> moves up 1 scope (either higher function, or global scope)
||
\\=>Global scope, foo not found, create foo globally! - hence, implied global
\\
\\=>foo can now be resolved to global variable, value undefined
Excessive DOM queries: your event-handler callbacks all look like so:
$('#box2').text(new_info);
This ($('#box2')) is actually the same as writing document.getElementById('#box2'). Which is practically English. Think about it like this: each time the client clicks on $(this) - whatever that may be, you're accessing the DOM, and scanning it for an element with a given ID. Why not do this once and use a reference kept in memory to change the text. That saves countless DOM queries.You could use a variable, or (in light of what I explained about closures), a closure:
var list = (function(box2, list, i)
{//list & i are arguments, so local to scope, too
for (i = 0; i < myArray.length; i++)
{
list += "<br>" + myArray[i].letter;//<-- don't know why you use this
//new_info = myArray[i].link; no need for this var
$(this).click((function(new_info)
{//new_info is closure var now
return function ()
{//box2 references DOM element, is kept in memory to reduce DOM querying
box2.text(link);
};
}(myArray[i].link));//instead of new_info, just pass value here
}
return list;//return string, assign to outer variable
}($('#box2'), ''));//query dom here, pass reference as argument
Where is the data supplied by the argument being stored? Is a var first being created implicitly?
function Student(first){
this.getFirst = function(){
return first;
}
}
Tested with:
var myStudent = new Student("ross");
console.log(myStudent); // Student { getFirst=function() }
console.log(myStudent.getFirst()); // ross
console.log(first); // reference error, first not defined
console.log(myStudent.first); // undefined
for(var x in myStudent){
console.log(x);
} // getFirst
My second question is if I understand these correctly:
What happens with "var" variables inside a JavaScript Constructor?
“var” variables, "this" variables and "global" variables - inside a JavaScript Constructor
...is the getFirst function creates a closure and saves the state of the constructor's parameter value, if I use a var first in the constructor body is it okay to think of that as 'encapsulation'? Additionally, any inner function saves all the parameter values in a "closure state" or just the one's referenced by the inner function?
Thank you very much for your thoughts. This is my first question on S.O. but use the site almost daily as a reference, so thank you for that. My programming knowledge is limited so pardon if I've used crappy terms, happy to clarify where needed.
The first parameter is stored locally to the function that is your constructor, so anywhere inside Student() it will be in scope.
More interestingly, the the anonymous inner function that you're assigning to this.getFirst is closing over that value. Because of that, the inner function maintains a reference to the first variable even after the constructor is finished executing.
This works for regular functions too, not just constructors:
function makeCounter() {
var count = 1;
return function() { return count++; };
}
var counter = makeCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3
When used the right way, this approach can be used to achieve "private" variables in JavaScript, in the sense that the values captured in the closure are inaccessible from the outside.
Because of that, it turns out not to matter whether a closure captures all the variables in its scope or just the ones it uses, since you can't "reach inside" to those closed-over variables anyway. (Though in practice generally only the used values are captured, so that the runtime can garbage collect the rest, as they're unneeded.)
To get a little further into what you're asking, it's not about creating a var, but rather in your instance the function also keeps the arguments array.
Your functions can happily create closures over both.
By returning functions from your function, those returned functions (or objects with functions as methods) have access to any and all vars and arguments, as long as you don't overwrite those functions.
The magic of closures.
I'm having a little difficulty with the inherent concept of a closure. I get the basic idea, but here's the thing: I thought that, technically, there "is a closure" inside every Javascript function. To quote wikipedia:
In computer science, a closure (also lexical closure, function closure
or function value) is a function together with a referencing
environment for the nonlocal names (free variables) of that function.
Such a function is said to be "closed over" its free variables.
So since you can define variables inside a function, they are "closed off" to the rest of your code, and so I see that as a closure. Thus, as I understand it:
(function(){var a = 1;}())
Is a (not very useful) example of a closure. Or heck, even just this:
function(){var a = 1;}
But, I think my understanding might be wrong. Others are telling me that for something to be a closure it has to persist a state, and so since nothing persists beyond that code it's not really a closure. That suggests that you need to have:
function(foo){foo.a = 1;}(bar); // bar.a = 1
or even (to ensure un-modifiability):
function(foo){var a = 1; bar.baz = function() { return a}}(bar); // bar.baz() = 1
So, technically speaking (I know several of the examples are practically speaking pointless, but) which of the above examples are actually examples of closures. And does a closure just have to be a space (ie. inside a JS function) where variables can be stored that can't be accessed form outside, or is persistence a key part of a closure's definition?
EDIT
Just noticed the wiki definition for the "closures" tag on Stack Overflow:
A closure is a first-class function that refers to (closes over)
variables from the scope in which it was defined. If the closure still
exists after its defining scope ends, the variables it closes over
will continue to exist as well.
While the SO wiki is certainly no final authority, the first sentence does seem to correlate with my understanding of the term. The second sentence then suggests how a closure can be used, but it doesn't seem like a requirement.
EDIT #2
In case it isn't clear from the varying answers here, the wikipedia answer, and the tag answer, there does not seem to be a clear consensus on what the word "closure" even means. So while I appreciate all the answers so far, and they all make sense if you go with the author's definition of closure, what I guess I'm really looking for is ... is there any actual "authoritative" definition of the word (and then if so, how does it apply to all of the above)?
You're being led astray by a wrong assumption of where the word "closure" comes from.
In a language-theoretic context, the point of a closure is that the function can refer to variables declared outside its own definition. It is immaterial whether it has internal variables, or that the internal variables are not visible from outside. In other words it is about seeing out from the function to its definition environment, not about seeing in from outside the function.
Why the weird word, then? Look at the function in your last example:
bar.baz = function() { return a }
This function contains a mention of the variable a which is not defined in the function body itself. It is a "free" variable of the function body, sort of a "hole" in the definition. We cannot execute the function without knowing, by some extraneous means, what variable the identifier a in the body refers to. Forming a closure at run-time pairs this "open" function body with a reference to the appropriate variable, thereby closing the hole in the definition. And that's where the name comes from.
(If you want the completely technical explanation, the underlying concept is that of a "closed" term in the lambda-calculus, which means one that has no free variables. Only closed term have independent meanings. A closure is then the combination of a (usually compiled) non-closed piece of source code, together with the contextual information that lets it behave like it was a closed term, and therefore be executable).
Addendum: In the common idiom
function() {
var blah;
// some code here
}();
the point is not to get a closure (you will get one, of course, but it doesn't do anything interesting for you), but to create a local scope for the blah variable. A local scope is conceptually quite a different thing from a closure -- in fact most C-lookalikes other than Javascript will create them at every {} block, whereas they may or may not have closures at all.
None of your samples are closures technically speaking. (But forth sample can be classified as such in some circumstances, see below)
Closure is a data structure that combines reference to a function and non-empty list of call frames (or scopes) active at the moment of declaration.
Closure is created by executing some code that contains declaration of a function that uses variables from outer scopes. In this case runtime, while executing the code, has to create not just a reference to the function but closure structure - function reference and reference to its current environment - list of call frames that hold used outer variables.
For example in my TIScript call frames are replaced on stack - when you exit from a function its call frame that includes collection of variables it uses is purged from the stack. Closure creation in my case happens when: VM meets function declaration instruction and that function is marked (by compiler) as the one that uses outer variables. In this case current chain of call frames that hold used variables is moved from stack to the heap - converted to GCable data objects and reference to the function and its call chain is stored as a reference.
Your fourth case physically does not require closure to be created - no need to store call frames for later use - bar.baz contains just a number - not a reference to function.
But this:
function(foo){
var a = 1;
bar.baz = function() { return a; };
}
creates closure in bar.baz field. When you later invoke bar.baz() function code is executed and value of 'a' variable will be taken from reference to outer call frame that is stored in closure.
Hope it clears something for you.
Closures in JavaScript (and other languages) are used to control and define scope. There's no requirement that you define a function within a function for it to "qualify" as a closure. The body of a function is a Closure. One of the more common uses is to declare a local scope variable that becomes a Private or Hidden member of some other object or function you'll return, but that's not a hard-fast rule.