I can't figure out why an unexecuted closure can capture the outer variables.
I do read about some articles about execute context, lexical environment, memory management, but none of these can solve my question:
function foo() {
var a = 1;
return function() {
console.log(a);
}
}
var f = foo() // line 7
// HERE variable a was been captured
f = undefined // line 10
// HEAE variable a was been released
When the engine execute to line7, the foo execution context was created above global execution context, but after line7 the closure was never been execute, so the closure execution context was never been created, so was the lexical environment. foo execution context was been popped up, the variable a will be released.
I can't find what's wrong with my point.
So why and when the variable in closure be captured?
function foo() {
var a = 1;
return function() {
console.log(a);
}
}
Function inside function are known as closure.
When one function has another function inside it, and say top level function has some data like 'a' in this case, then all the inner functions will get access to that data, this will happen only if inner function has some reference about those variables.
Let's say if you have 'b' variable beside 'a' and you are not using it anywhere in inner functions this will be simply ignored by javascript. 'Closure' will not hold this value like 'a'.
This is actually where closure gives devs power.Check out below example -
const test = (num1) => (num2) => console.log(num1*num2);//closure is in action here
var s = test(100)
s(2); // this will give output of 200
Hope this helps.
Thanks.
Here is a discussion on bugs.chromium that is related to your question. As per this , even when the else block never executed , reference to an outer object used in function returned by else block is created and stored in heap. It is never garbage collected. Refer to below discussion :-
https://bugs.chromium.org/p/chromium/issues/detail?id=315190
The key point is lexical scope:
Lexical scope is the scope model used by the JavaScript language, which differs to some other languages which use dynamic scope. Lexical scope is the scope defined at lexing time.
Considering this:
var a = 1
console.log(a)
console.log(b)
var b = 2
console.log(c)
You can get the result:
1
undefinded
ReferenceError: c is not defined
So, you can see how JavaScript handling the variables: all variable are defined at lexing time and assignment at runtime. This is what they called hoisting.
Back to the question: closures capture variables at lexing time in which js engine read your code and defined variable and bind them.
Read more about compilation at: https://v8.dev/blog/background-compilation
Related
I have read this excellent piece:
How do JavaScript closures work?
But I still have questions...
StackOverflow tags defines "Closures" as "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".
When my functions end with a return, do all variables defined within them get deleted and memory allocation made free? It appears to me that conditions exist when one could answer yes or no.
Yes, I know memory is plentiful and free but that is not my question.
Think of an intranet based application which ajax's data back and forward during a working day. As data is received by the client, massaged, and no longer required, it can be dispensed with. Poor programming technique could result in a build up of data no longer user or required (or worse, data being used that is out of sync).
Reading the piece on closures above tells me that some variables within a function can still be referenced from outside the function scope. I am guessing that I will need to re-read the closure document several times as perhaps I've not fully understood it.
Can someone share an example on where a variable continue to exist?
And... Do I gain any benefit if, at the begining of each function I declare my variables, and prior to using a "return true;" if I reassign the variables a value of null?
All help appreciated...
num will exist within a function outside of IIFE c which returns a
var c = (function() {
var num = 10;
var a = function a(n) {
console.log(n)
return n * Math.random()
};
return a.bind(null, num)
}());
var res = [c(), c(), c()];
console.log(res)
When you return true from a function you don't have a closure. You have a closure when you return a function from a function, like this:
function makeAdder( firstNumToAdd ){
return function( secondNumToAdd ){
return mainNumToAdd + secondNumToAdd;
}
}
var add3 = makeAdder(3);
var seven = add3(4);
In the above example, the variable firstNumToAdd, although is scoped to the function makeAdder is always accessible to the inner function, even though the function exited after executing the line var add3 = makeAdder(3);
Please correct me if I am wrong, but I don't think that
some variables within a function can still be referenced from outside the function scope
is true.
Closures remember the context of a function call and bind the relevant variables (i.e. this, etc) to the closure's scope. If that is correct, then calling the closure again would cause the old variables' values to get garbage collected and you wouldn't have to worry about memory waste or out of sync data.
obj = {
func: function(){
var test = 'preserved value';
this.func2 = function(){
console.log(test);
};
}
};
obj.func();
obj.func2(); //'preserved value'
obj.func = undefined;
obj.func2(); //'preserved value'
As you can see, even after completely blowing away the original scope (func) the enclosing scope retains the test var.
How the variable 'str2' is available inside the callback method passed to display method?
str2 should be visible only inside function 'name'.
a = {
display: function (n){
console.log("I am inside display method");
n();
}
}
function name(a,str2)
{
a.display(function (){
console.log(str2);
})
}
name(a, 'ddd');
Variable scoping in Javascript is hierarchical. Lower scopes have access to all variables of all higher scopes. Here's an example:
function outer() {
var foo = 2;
function inner() {
console.log(foo); // 2
}
}
It doesn't matter if a variable is passed as a parameter or if it was defined as a local var.
Yes str should be visible only inside function 'name' yes it is working same you said, in JavaScript function declarations loads before any code is executed, and scope depend on execution context
in your code scope of str2 is inside name() function and you call a.display() within this scope (within scope of name()) that's why str2 available inside display() at the time of execution.
To evaluate name(a, 'ddd'), the compiler will create a new stack frame and place two slots on it, one a, which will be a reference to the global object of the same name, and str2, which will contain the string literal 'ddd'. Then the body will be evaluated.
In the body, to evaluate a.display(function(){...}), the value of a.display will be resolved to the function with parameter n. To evaluate n(function(){...}), a new stack frame will be created with n assigned to the closure that results from evaluating the anonymous callback (a closure being a combination of a pointer to the static scope of the function and the compiler generated code for the function itself). Then the body of the a.display function will be evaluated.
In the body, the console.log will be called with the given string. Then the callback n() will be evaluated. Since n doesn't take any parameters, it will just be evaluated in the topmost stack frame, so when the time comes to evaluate console.log(str2), str will not be found on the current stack frame, so the compiler will follow the scope chain all the way to the frame where we bound 'ddd' to str and a to the function.
That's a pretty long answer to your simple question. I'll try to shorten it later. Also, corrections are welcome, as I'm being very hand-wavy with the evaluation process.
In Javascript the variable declared on a certain scope is available in every inner scope. In this case it's a concept called "closure". This answer might give you good insight about scoping in Javascript: What is the scope of variables in JavaScript?
Hope this simple example can help you understand its usefulness:
function counter () {
var votes = 0;
this.upvote = function() { votes++; }
this.downvote = function() { votes--; }
this.getValue = function() { return votes; }
}
var counter1 = new counter();
counter1.upvote();
console.log(counter1.getValue()) // Prints 1
counter1.upvote();
counter1.upvote();
console.log(counter1.getValue()) // Prints 3
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Consider the following code:
function nepaliBuddha() {
var a = 20;
return function buddhaNepal() {
console.log(a);
}
}
var closure = nepaliBuddha();
closure(); // logs 20
Now when we invoke closure output is 20. This proves that the internal scope property ([[scope]]) was assigned to the inner function where it was defined or say when declared.If this wasn't assigned at declaration ,there was no way to log 20 as it gets invoked in different context
Invoking closure() the scope chain of a function context is created at function call and consists of the activation object or VO of the current context and the internal [[scope]] property of this function.
Invocation also creates [[scope]] property , this means that internal scope property is created at declaration as well as at execution isn't it?
Usually the definition says the [[scope]] property gets created at run time or at function call but this isn't true as [[scope]] property is already assigned at declaration as well.
What I think is the [[scope]] property might get updated after execution of function, is it? Please give clear definition of [[scope]] internal property. How and when it is created at declaration time or at execution time or at both time.
Wow, aren't you thoroughly confused. Alright, I'll try to explain closures as simply as possible.
First, we'll start with scopes. There are two types of scopes:
Block scopes
Function scopes
A block scope begins immediately when it occurs in the program. A function scope on the other hand does not begin until the function is called. Hence multiple calls to the same function result in multiple scopes being created.
JavaScript does not have block scopes. It only has function scopes. Hence to emulate a block scope we need to create a function expression and immediately execute it. This patttern is called an immediately invoked function expression (IIFE) and it looks like this:
(function () {
// this is the JS equivalent of a block scope
}());
Beside block scopes and function scopes there's another way to classify scopes. Hence we also have:
Lexical scopes
Dynamic scopes
This distinction only applies to function scopes because block scopes are always lexically scoped. JavaScript only has lexical scopes.
To understand the difference between lexical scopes and dynamic scopes we need to understand the difference between free and bound variables.
A free variable is a variable which is used within a function but which is not declared within that function.
A variable which is declared within a function is said to be bound to that function.
Consider the following program:
function add(x, y) {
return x + y; // x and y are bound to add
}
In the above program the variables x and y are bound to the function add because they are declared within add.
On the other hand the variables x and y in the following program are free within the function add because they are not declared within add but they are used within add:
function add() {
return x + y; // x and y are free within add
}
Now free variables are a problem. They need to be mapped to some value, but which value? This is where lexical and dynamic scopes come into picture. I won't go into the major details, but you can read about it on Wikipedia.
Scopes are a lot like prototypal inheritance. When a new scope begins it inherits from a parent scope forming a chain of scopes much like prototype chains in JavaScript.
Lexical scopes and dynamic scopes differ with respect to which parent scope a new scope inherits form.
In lexical scoping a new function scope inherits from the scope in which that function was defined (i.e. its lexical environment).
In dynamic scoping a new function scope inherits from the scope in which that function was called (i.e. the calling scope).
Since JavaScript only has lexical scoping we won't bother with dynamic scoping. Consider the following program:
var count = 0;
function incrementCount() {
return ++count;
}
(function () {
var count = 100;
alert(incrementCount()); // 1
}());
Here the function incrementCounter has one free variable - count. Since JavaScript has lexical scoping count will be mapped to the global variable count instead of the local count declared within the IIFE. Hence incrementCount returns 1 and not 101.
Now closures only work in languages which have lexical scoping. Consider the following program:
function getCounter() {
var count = 0;
return function () {
return ++count;
};
}
var counter = getCounter();
alert(counter()); // 1
alert(counter()); // 2
alert(counter()); // 3
In the above program the function returned by getCounter is a closure with respect to the variable count because:
The variable count is free within the returned function (i.e. counter).
The function is moved outside of the scope within which count is declared.
Both these conditions are necessary for a function to be called a closure. For more information read the following answer: https://stackoverflow.com/a/12931785/783743
Now the important thing to understand here is that the function counter will still be called a closure even though it may never be invoked. A closure is simply a function which closes over a variable (which is called the upvalue of the closure).
When we invoke getCounter we create a new scope (let's call this scope A), and each time we invoke the function returned by getCounter (i.e. counter) we create a new scope which inherits from scope A. That's all. No new closure is created.
A closure is a special kind of object that combines two things: a function, and the environment in which that function was created. The environment consists of any local variables that were in-scope at the time that the closure was created.
function makeFunc() {
var name = "Mozilla";
function displayName() {
alert(name);
}
return displayName;
}
Now call makeFunc()
var myFunc = makeFunc();
myFunc();
In this case, myFunc is a closure that incorporates both the displayName function and the "Mozilla" string that existed when the closure was created, MDN.
So, the scope created exactly when I called var myFunc = makeFunc(); and myFunc() (the result of the makeFunc() call) is now a closure. So, go to the first line where
A closure is a special kind of object that combines two things: a
function, and the environment in which that function was created.
Now consider these
function nepaliBuddha() {
var a = 1;
return function buddhaNepal() {
a = a+1;
console.log(a);
}
}
var closure1 = nepaliBuddha(); // An individual scope
var closure2 = nepaliBuddha(); // An individual scope
closure1(); // 1
closure1(); // 2
closure2(); // 1
closure2(); // 2
closure2(); // 3
Demo.
Which means, closure1() and closure2() are closures and both have their personal scope/environment and they have access to their own scope once they get it (in this case, every time you call nepaliBuddha you are creating a closure and giving/saving it to a variable).
Scope defines the area, where functions, variables and such are available. So, when you defined/declared the function buddhaNepal (inner function) inside the nepaliBuddha (outer function) the buddhaNepal (inner function) has been just separated from the global scope and nothing else. It can't access anything in the global scope but it has it's own scope, that's it. The nepaliBuddha (outer function) is the boundary of the buddhaNepal (inner function) and in this case the nepaliBuddha outer function's local scope/environment is the global scope for the buddhaNepal (inner function).
in JavaScript, this is known as Lexical Scopeing it defines how variable names are resolved in nested functions. Other names of Lexical Scope are Static Scoping or Closure. It means that the scope of an inner function contains the scope of a parent function.
In Javascript, I am sometimes too immerged in the idea that a function creates a new scope, that sometimes I even think the following anonymous function will create a new scope when it is being defined and assigned to onclick:
ha link 1
ha link 2
ha link 3
ha link 4
ha link 5
<script type="text/javascript">
for (i = 1; i <= 5; i++) {
document.getElementById('link' + i).onclick = function() { var x = i; alert(x); return false; }
}
</script>
but in fact, the anonymous function will create a new scope, that's right, but ONLY when it is being invoked, is that so? So the x inside the anonymous function is not created, no new scope is created. When the function was later invoked, there is a new scope alright, but the i is in the outside scope, and the x gets its value, and it is all 6 anyways.
The following code will actually invoke a function and create a new scope and that's why the x is a new local variable x in the brand new scope each time, and the invocation of the function when the link is clicked on will use the different x in the different scopes.
ha link 1
ha link 2
ha link 3
ha link 4
ha link 5
<script type="text/javascript">
for (i = 1; i <= 5; i++) {
(function() {
var x = i;
document.getElementById('link' + i).onclick = function() { alert(x); return false; }
})(); // invoking it now!
}
</script>
If we take away the var in front of x, then it is a global x and so no local variable x is created in the new scope, and therefore, clicking on the links get all the same number, which is the value of the global x.
Update: the question is: we have to be careful when we analyze code, that a function will not create a scope when it is merely defined and assigned. It has to invoked. Is that so?
You're right, but you're also confusing yourself. Rather than thinking of functions as just "making a new scope" understand what's really happening instead. Javascript interprets a variable by looking at a scope chain. If the variable is not present in the function's scope, it will go up to the enclosing level's scope in the case of a closure. That part happens at the time the variable is interpreted. The scope itself is created when the function is, but where you're getting confused is nothing is "captured" in the scope at that time. It's just augmenting a scope chain.
That's why putting closures in loops is such a "gotcha" in javascript programming--you are right to put in in an auto-executing anonymous function if you want to capture the value of i at the time of function declaration. People tend to think (especially coming from procedural languages) that the outer scope is frozen and all current values are passed into the new function scope, and that's not true.
The Scope of a function is set when the function object is created, for example:
var fn;
// augment scope chain:
with ({foo: "bar"}) {
fn = function () { // create function
return foo;
};
}
// restored scope chain
fn(); // "bar"
In the above example, the function is created inside the with block, there the current scope is being augmented, to introduce the object with the foo property to the scope chain.
In your second example, happens the same, the onclick handler function is being created inside the auto-invoking anonymous function, which itself has created a new lexical scope.
At the moment that function is auto-invoked on each loop iteration, the value of i is captured into that scope in the x variable, then the onclick handler function is created inside that scope, and it will be able to resolve it.
I do not understand your question, but I do not see anything weird or wrong with that.
In the first case, a closure is formed, and when the event is invoked, it creates its own scope and fetches the value from i in its outer scope, maintained due to the closure. But that code has already been executed so i = 6 because the loop is long finished, and thus, x = 6.
In the latter example, its the same thing, you are creating a closure, and when the event gets invoked it will fetch x from its outer scope, maintained by the closure, but it already executed, and since it ran immediately in the loop, this time x is equal to the i at the time the function was ran (to create the closure).
I've reading scope chain in Javascript but it didn't make any sense to me, could any one tell me what is scope chain and how it works with a graphic or something even an idiot can understand. I googled it but I didn't find something comprehensible :(
To understand the scope chain you must know how closures work.
A closure is formed when you nest functions, inner functions can refer to the variables present in their outer enclosing functions even after their parent functions have already executed.
JavaScript resolves identifiers within a particular context by traversing up the scope chain, moving from locally to globally.
Consider this example with three nested functions:
var currentScope = 0; // global scope
(function () {
var currentScope = 1, one = 'scope1';
alert(currentScope);
(function () {
var currentScope = 2, two = 'scope2';
alert(currentScope);
(function () {
var currentScope = 3, three = 'scope3';
alert(currentScope);
alert(one + two + three); // climb up the scope chain to get one and two
}());
}());
}());
Recommended reads:
JavaScript Closures
Closures
Any function call in ECMAScript ( core language that JS is based on ) produces a separate execution context, which run individually from one another. Inside of each execution context, this refers to the object in question, defaulting to whatever the function is attached to.
function foo() {
alert(this===window)
}
Would alert true, because the window is the object which owns the 'foo' method. Any variables defined in a function become accessed through that function's unique scope chain, environment.
function world() {
var name = 'global';
alert(name)
}
would alert 'global' obviously.
function world() {
var name = 'global';
(function() {
var name = 'country';
alert(name)
})();
alert(name)
}
In the latest example, when the first alert is invoked, Javascript determines that in the scope chain of the inner function that the identifier name is defined, so it doesn't have to look up the scope chain to grab it.
In the second alert invocation, name is also defined in the same context and alerts 'global';
function world() {
var name = 'global';
(function() { alert(name) })();
}
In this example, the name identifier is not defined in the same context and thus it has to travel up the scope chain to the outer function where name is defined, and it alerts global.
Reference:
http://www.digital-web.com/articles/scope_in_javascript/
http://www.jibbering.com/faq/faq_notes/closures.html
I know it's an old post but it is still helpful for developers. I wanted to do it little different way as it would be more friendly for beginners to understand scope chaining. Here is my modified version of code:
var currentScope = 0; // global scope
function a () {
var currentScope = 1, one = 'scope1';
alert(currentScope);
function b () {
var currentScope = 2, two = 'scope2';
alert(currentScope);
function c () {
var currentScope = 3, three = 'scope3';
alert(currentScope);
alert(one + two + three); // climb up the scope chain to get one and two
}
c();
}
b();
}
a();
This is about closure. You may use variables outer from scope in the inner scope:
function get_inner_scope () {
var outer = 'Outer variable value';
return function () {
alert(outer);
}
}
f = get_inner_scope();
f(); // alerts Outer variable value
More deatailed info with other samples by first google's link:
http://blogs.msdn.com/jscript/archive/2007/07/26/scope-chain-of-jscript-functions.aspx
Summary:
The scope chain is used to resolve the value of variable names in javascript. Without a scope chain the Javascript engine wouldn't know which value to pick for a certain variable name if there are multiple defined at different scopes. Scope chain in javascript is lexically defined, which means that we can see what the scope chain will be by looking at the code.
At the top of the scope chain is the global scope, which is the window object in the browser (global in NodeJS). Besides from the global scope, functions have their own scoping of variables. The scope chain can be determined by looking at where functions are defined.
When resolving a variable, inner functions first look at their own scope. If the variable cannot be found in its own scope it will climb up the scope chain and looks for the variable name in the environment where the function was defined. This look like this:
So in our image example when innerFoo uses the variable bar it first tries to find it within the scope of the innerFoo (code within function body). Then when it doesn't find it here it climbs up the scope chain to foo. In foo there is also no variable which is named bar. Therefore, it will climb up the scope chain and now look in the global scope. In the global scope is a variable named bar with a value of 10 to which bar will be resolved.
Example:
let foo = 1;
let bar = 1;
function test (bar) {
return function innerTestFunc () {
let foo = 10;
console.log(foo, bar);
}
}
const innerTestFunc1 = test(5);
const innerTestFunc2 = test(20);
innerTestFunc1(); // logs 10, 5
innerTestFunc2(); // logs 10, 20
In the above example we have a function which returns a function. We first store this function in the variables innerTestFunc1 and innerTestFunc2. This creates a closure which is basically a snapshot of the scope chain of the outer environment.
Then when the functions are executed the function requires a value for both the variables foo and bar. The value of foo can be resolved at the level of the innerTestFunc and is 10 for both. 10 is already found in innerFoo, so no need to climb the scope chain for foo.
In the case of the bar variable the function cannot find it in the innerFoo. Therefore, it will climb up the scope chain. It first encounters the variable bar in the function test, therefore it will resolve value of bar to whatever the value is in the test function (5, 20 in our example).
Scope chain in Javascript explained in layman terms
Alex is a happy guy,One fine day,walking down the road with his monthly salary in hand gets mugged.
Later he realizes that tomorrow is the last day to pay for his daughters tuition of 1000$.
He runs home,finds his savings of 400$,worries about the rest(600$).The immediate thought that flashes,is to borrow some from his father Mathew.
Mathew,the poor carpenter,devoid from any money sells his inherited bracelet for 300$ and lends it to his son Alex.
Alex having a good reputation in the society,gets the remaining 300$ from a local bank immediately and pays his daughter tuition on time.
Coming back to Scope chain in Javascript:
Alex-A function in javascript
Mathew-The immediate function,Alex is nested in.
Mathews parents-The immediate function Mathew is nested in.
Bank-Global variables.
function Bank() {
loan=300;
Mathew();
function Mathew() {
mathew=300;
Alex();
function Alex() {
savings:400;
alert('I need some money');
}
}
}
Bank();
Scope chain of Alex at this point looks like:
[savings:400]+[mathew:300]+[loan:300];