This question already has answers here:
Is it true that every function in JavaScript is a closure?
(2 answers)
Closed 3 years ago.
I have been reading a fair bit about closures in JS.
I have been through various guides as this one https://medium.freecodecamp.org/javascript-closures-simplified-d0d23fa06ba4
I still have one question though. Does a closure only refere to first order function (function returning a function). Or, is any function a closure ?
The only difference I see really is like with some function not nested, one of the 3 scope chain (outer function's scope) would be empty still it doesn't exist.
A closure is created by calling a function; the function itself isn't the closure. Conceptually, every function call implicitly causes a new closure to come into existence. For some functions, the closure is ephemeral and just vanishes as soon as the function returns:
function add2(n) {
return n + 2;
}
That function returns only a number; nothing can refer to anything in the closure created by the function call, so the closure goes away and all you have left is the return value.
The closure becomes interesting when a function returns something that has one or more "hooks" into the local environment created when the function was called. (The function can expose the closure by modifying the global environment too.) So this function:
function addn(addend) {
return function(n) {
return n + addend;
}
}
exposes the closure because the returned function has a reference to the parameter of the outer function.
I can't think of a way an ordinary function can expose a closure that doesn't somehow involve one or more functions that reference stuff from the local context (parameters, variables). (Generator functions are interesting, because yield kind-of always returns something that exposes the closure, I suppose.)
A closure is the combination of a function and the lexical environment within which that function was declared
for example,
function greet(Say){
return (
function(name){
console.log(Say + ' ' + name);
}
)
}
Now I'm I can do something like this,
greet('Hi')('Alex')
This line will return the string 'Hi Alex'
Now I'm going to do something like this,
var sayGreet = greet('Hi');
If I console.log(sayGreet) it will be a function.
Now tell me where is this sayGreet variable defined? It is on the global level. Or in the other word global execution context.
Now let's do,
sayGreet('Alex')
inside this sayGreet function, we have a console.log(Say + " " + name) . We know name is Alex but what about Say? There is no sign of Say at this moment because the greet function already completed execution and returned a function.
Even though javascript still have the ability to refer to the Say value. Even it is completed the execution. This Say value can only be access by inner functions or nested functions.
This is call closure. A single function cannot be closure. There should be an outer lexical environment too.
Related
This question already has answers here:
How do JavaScript closures work?
(86 answers)
Closed 1 year ago.
I came across this while watching a video and though they did a good job explaining closures, they did not really explain how the functions were linked. So, I still did not understand how calling newFunction('inside') somehow set the values for both outerVariable and innerVariable. Can anyone explain how this works? Here's the code:
function outerFunction(outerVariable){
return function innerFunction(innerVariable) {
console.log('Outer Variable ' + outerVariable)
console.log('Outer Variable ' + innerVariable)
}
}
const newFunction = outerFunction('outside')
newFunction('inside')
This line:
newFunction('inside')
does not set outerVariable. What happens here is a classic javascript closure.
A closure gives you access to an outer function’s scope from an inner function.
In this case:
const newFunction = outerFunction('outside')
will return a new function (in our case its innerFunction) and innerFunction when called will have access to its to its surrounding state (the lexical environment). In this case, our surrounding state is outerVariable variable.
So basically, at this point its similar to this:
var outerVariable = "outside"
function innerFunction(innerVariable) {
console.log('Outer Variable ' + outerVariable)
console.log('Outer Variable ' + innerVariable)
}
And when you call innerFunction with "inside", ofc innerVariable will be "inside" and outerVariable will have a value of "outside".
This is a classic closure.
when you called the outerFunction in this line:
const newFunction = outerFunction('outside')
newFunction saved innerFunction as the return value. The principle of closure makes sure that newFunction also received all the execution context of innerFunction along with it.
Which means that it receives the variable outerVariable which has the values outside that got passed to it in the above line.
Thats how it can print not only innerVariable which you passed while invoking newFunction but also the value of outerVariable.
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'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
I have a function which allows user to pass a function.
function withPredicate(func){
//...
}
Inside my function, I need to detect whether the func that user pass in has closure or not.
It is not enough to get the function name and search it in window scope. User might pass in an anonymous function without closure like:
var func = function(x){return x;};
withPredicate(func);
EDIT:
I think I need to implement a function which takes a function as a argument and return bool.
function hasClosure(func){
//...
}
so several test cases are:
hasClosure(function(x){return x;}); //return false
var something = 30;
var func1 = function(x){return x.age < something;}
hasClosure(func1); //return false
var Closure = function(){
var something = 18;
var itself = function(x){
return x.age < something;
};
return itself;
};
var func2 = new Closure();
hasClosure(func2); //return true
The last one return true because func2 is not top-level function. When I see some free variable inside the function body like something, it may resolve to the variable defined in its closure other than the one defined in window.
Actually, what I need to do now is to do some manipulations based on the func that has been passed to my function. I can use JSLint to get the undeclared variable. But I also need to resolve these variables. It is acceptable that I can only resolve variables in global scope. But I still need a way to make sure that resolving these variables in global scope is correct. So I need to detect closures.
Is it possible to do that programmatically in javascript?
Alright this is really hacky and probably not worth the effort in actually writing unless your linting or something :)
Basically what you're going to have to do to determine if a function is a closure is call func.toString() which will give you the source of the function. You can then parse the function using some sort of parser which determines all the variables of the function func. You also need to determine and track how these variables are defined. In your criteria in op the criteria for it being a closure is having a variable that is defined outside of function scope and outside of window scope (thus closure scope). So if you can find any variables defined outside of these two scopes we've found a closure.
So heres the pseudocode of hasClosure(), have fun implementing.
func hasClosure(func)
source = func.toString(); //eg "function x(a) {return new Array(a)}"
variables = parseJSForVariables(source)//finds a and Array
for variable in variables:
if(variable not in window)
if(variable not defined in function)
return true //we got a closure
return false //not a closure
The correct answer highly depends on what a "closure" means in this context. The function from the question does not use the variables from the outer scope so, roughly, closure is not created for this function. But strictly speaking, closure is created for any function and binds definition context with the function. So whatever you want to detect, it requires a detailed specification.
But I can assume that the closure here means whether the function references variables declared in outer scope (just like https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures specifies). One of the static for analysis libraries can be used for this. For example, JSLint reports used but undeclared variables. Assuming that undeclared variables are just from the upper scope, this indicates that closure is created.
I'm quite still confused with the concept of closure in JavaScript. I get the point that closure is the ability of the inner function to access the variable created within its mother function after the mother function has returned.
But I'm still confused why do we have to create inner function to protect the local variable if we could just create a variable inside the function?
We need to create an inner function so that the variables in the outer function have some existence after the outer function returns.
Consider a simple function:
function f() {
var x = 0;
return ++x; // x=1
} // Once the function has exited then "x" no longer exists.
Note that the variable "x" is only "active" (alive, existent) when control of the program flows from the start of the "f()" function to the end of it. But if we enclose "x" in an inner function then x will live as long as the inner function does:
function g() {
var x = 0;
return function() {
// Now "x" will live for as long as this function.
return ++x;
}
};
var counter = g();
counter(); // => 1
counter(); // => 2
counter(); // => 3
Now when we call "g()" we get another function, and "x" is active for as long as that function is referenced by a variable.
Why use closure?
(function(){
var current_page = 1;
function previous_page() {
current_page--;
// update interface
}
function next_page() {
current_page++;
// update interface
}
// a bit of jQuery, ok?
$('#previous').click(previous_page);
$('#next').click(next_page);
})();
Look: we have no global variables, not even any function defined in the global space... yet, we have attached a behaviour to the click events of "#previous" and "#next" buttons for a paging feature. How would you do it without closures? How would you do it defining current_page variable inside the functions?
You just answered your question, the inner function protects it's variable. jsFiddle
(function outer(){
var foo = 'bar';
function inner(){
var foo = 'OMG NO!';
}
alert(foo);//alerts 'bar'
})()
FROM MDN CLOSURES
why to use:
A closure lets you associate some data (the environment) with a function that operates on that data. This has obvious parallels to object oriented programming, where objects allow us to associate some data (the object's properties) with one or more methods.
when not to use
It is unwise to unnecessarily create functions within other functions if closures are not needed for a particular task as it will negatively affect script performance both in terms of processing speed and memory consumption.
For instance, when creating a new object/class, methods should normally be associated to the object's prototype rather than defined into the object constructor. The reason is that whenever the constructor is called the methods would get reassigned (that is, for every object creation).
The reason you need to create the inner function with scoped variables is object oriented encapsulation. It's essentially private variables.
The variables are "closed over".
// constructor function
var myObject = function(message) {
// private - scope is function level. It's CLOSED OVER the the inner function (closure).
// not delcared as a JSON property so not visible externally
var value = 0;
// constructor returns JSON object with public methods
// always constructed from the myObject var so it always hands back the same instance
// of the public methods
return {
// nested functions have access to outer function variables.
increment: function (inc) {
value ++;
},
getValue: function() {
return value;
},
// the inner function even has access to the outer function's args!
getMessage: message
}
};
Look at the return statement. It returns the public interface - some methods that have access to the private variable because they are in the inner function. It's using JavaScripts function scoped variable to create object oriented encapsulation.
After that I can it like:
var obj = myObject('Hello World');
obj.increment();
obj.increment();
console.log(obj.getValue());
console.log(obj.getMessage);
// should be undefined
console.log(obj.value);
Note at this point the consumer does not have access to the protected/encapsulated value or message.
Now, here's the kicker - the object is mutable so the caller can add methods or even replace methods. So, you would think someone could add a method that exposes the internals. But, they can't because of function scope (closure - they're closed over). Only the nested function has access to the variables of the outer function. So, if the caller adds a method to return the internal, they can't get access and it will be undefined.
The code above outputs:
2
Hello World
undefined
As a side note, I'm running the javascript with node.js
Here's a good blog post on the module pattern using closures:
http://www.yuiblog.com/blog/2007/06/12/module-pattern/
The point is that the variable is shared between the two functions. If you declared the variable in the inner function, then the outer function would not be able to access it, so it wouldn't be shared.
If you declared the variable in the inner function, then each call to the inner function would create a new variable: any modifications made by a previous call are lost.
But if the variable is declared in the outer function then multiple calls to the inner function would see the same variable and one call would see the modifications of a previous call so long as they were both scoped to the same version of the outer function.
There are alot of right answers out there about closures, but it always seems to get really technical while many people asking might be looking for a higher level simple explanation first.
I like to think of it like a car. When you drive a car, there are many many complex processes going on, but the average person doesn't need to know about these on an average day. Think of all those complexities as "private" variables hidden away by closures which makes the gas pedal, the break, the shifter, the steering wheel, and so on a lot easier to use.
So what is the purpose of a closure? To hide away all the complex variables and such to make a script much more usable. If you had to worry about every variable in a script everytime you wanted to use any function in the script, well that could quickly get very difficult. YAY CLOSURES!