function one() {
function two() {
alert(i);
}
return two;
}
(function() {
var i = 3;
var f = one();
f(); // Uncaught ReferenceError: i is not defined
}());
The articles I've read say that, when a function is called, a new execution context is added on to the stack and the scope chain is created by traversing up the stack. But surely that would result in 3 being alerted in the above code?
How does it work out the scope chain?
The scope chain is determined by the lexical nesting of scopes. The scope can be affected dynamically (via with), but that causes a lot of problems. It's definitely not the case that the current stack of function activations has anything to do with scope.
When you do var i = 3;, you are creating a local variable that exists only in the scope of the immediately-invoked function expression (IIFE).
Any functions that are defined in that scope can access the variable i.
one() (and therefore also two()) was declared outside the scope, so it has no idea what i is. It's looking up its scope chain to window.i, which doesn't exist.
The call stack (as mentioned keeps adding an execution context to the top of the stack when a function is invoked) and lexical scope (which allows access to variables from outer scope) are independent of each other.
Lexical scope depends only on where the function is created not where the function is invoked, so in your example function "two" is created inside function "one", so when variable "i" inside function "two" tries to access "i", it tries to find "i" in its own scope first, since there is no "i" defined it will go out to the scope where the function is created in your case its function "one" (not where the function is invoked in anonymous IIFE below) and it couldn't find variable "i" again inside function "one", now since function "one" is defined inside global scope (the default execution context) JS will try to find the value of "i" inside the global scope which results in "undefined".
In order to access variable "i" you need to move function "two" into anonymous IIFE as shown below, function two has outer lexical scope of function "one" which has an outer lexical scope of anonymous IIFE which has i assigned to 3 which is alerted.
(function () {
var i = 3;
function one() {
function two() {
alert(i); // will alert 3
}
return two;
}
var f = one();
f();
}());
Hope this is clear now :)
The call stack and the execution context stack are not the same. A function call adds a level to the call stack, but execution context stacks are not changed. However, the function that you call has a different execution context stack.
Each function scope has its own execution context stack which is determined by where the function is created, it doesn't inherit the execution context stack from the calling code.
If you nest functions in each other and only call the inner functions, like in the first example on the page, the call stack and the execution context stack will happen to correspond.
Execution stack is what happens on hardware (memory), regardless of whatever high level language is running. The scope chain model is managed by specific interpreter to implement programming language features such as functional programming, which itself is another program independent from the one you've written, the sequence of function call stacks via the interpreter is different from the actual order on physical hardware.
Related
const var1 = 8;
const var2 = 9;
function func1(){
console.log("Inside func1")
}
func1();
When above programme will be executed a global execution will be created Inside Global execution two variables var1 and var2 will be created during the creation phase of global execution context and values 8, 9 will be assigned inside these variables during execution phase of global execution context
so my question is what will happen with function identifier func1.What will be stored inside a variable name
func1 in memory when it get declared in global phase. Also how function declaration works under the hood how and where function are stored in memory`
When the above program is executed, during the creation phase of the global execution context, the function identifier func1 will be hoisted to the top of the scope, and a reference to the function object will be stored in memory. This means that the func1 variable will be assigned a reference to the function object even before the function is declared, and it can be called from anywhere in the code.
The function declaration works by creating a function object that consists of the function code and a reference to the surrounding scope. This function object is stored in memory in a specific location, and the function identifier is assigned a reference to that location. When the function is called, a new execution context is created, and the function code is executed in that context.
It's important to note that function expressions, as opposed to function declarations, are not hoisted to the top of the scope, and their identifiers are only available within the scope of the expression itself.
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
In the You Don't Know Javascript series, 1/3 of the way down IIFE's are described as not being closures themselves, but only if they're executed outside their lexical scope:
Chapter 3 introduced the IIFE pattern. While it is often said that
IIFE (alone) is an example of observed closure, I would somewhat
disagree, by our definition above.
This code "works", but it's not strictly an observation of closure.
Why? Because the function (which we named "IIFE" here) is not executed
outside its lexical scope. It's still invoked right there in the same
scope as it was declared (the enclosing/global scope that also holds
a). a is found via normal lexical scope look-up, not really via
closure.
var a = 2;
(function IIFE(){ // not actually a "closure"
console.log( a );
})();
In this SO post, the following snippet was given as an example of a closure:
for (var i = 0; i < someVar.length; i++)
(function (i) {
window.setTimeout(function () {
alert("Value of i was "+i+" when this timer was set" )
}, 10000);
})(i);
I am trying to understand this in terms of the definition of closure (as defined in this medium article):
To use a closure, simply define a function inside another function and
expose it. To expose a function, return it or pass it to another
function. ...
The inner function will have access to the variables in the outer
function scope, even after the outer function has returned.
I understand that a closure is a "stateful function", and that it is
a way to "remember" and continue to access a function's scope (its
variables) even once the function has finished running.
So in this example, I see that the loop's i is remembered when passed into the closing IIFE.
My question is:
Where is the "passing to another function or returning" portion happening? My guess is that the IIFE is able to remember the outer i for loop value at each iteration because the IIFE is passed to the window?
Basically, my understanding is that a closure is defined as remembering an outer scope's value after the Garbage collector cleans that outer scope up, and that the usage of it is to expose the closure by returning it and accessing it outside its lexical scope. Is this correct? So where is that "accessing it outside the lexical scope" happening?
in this example, I see that the loop's i is remembered when passed into the closing IIFE
No. The IIFE is only providing the scope for the i value to be remembered. As the quotes you cited state, the IIFE function is not a closure. The function expression that uses the i is the closure:
(function IIFE(i) {
// this is the scope of i
window.setTimeout(function closure() {
// this function closes over i
alert("Value of my local 'i' is still "+i+" even after 10 seconds");
}, 10000);
})(0);
// ^ this is some arbitrary value passed to the IIFE - it could have been a loop variable
Where is the "passing to another function or returning" portion happening?
It's the closure function being passed into setTimeout, which will call it back from a place where i would usually be no longer defined - if it wasn't a closure.
I have some trouble to understand the Javascript execution context
see below code:
<script >
var global_var;
first();
function first() {
var first_var = 'a';
second();
}
function second() {
var second_var = 'b';
console.log(first_var);
console.log(second_var);
}
console.log('in the outer');
//second();
</script>
Based on my understanding, when first function call the second function, the second function is inside first function's execution context, so, the second can also access first function's properties, here is first_var
But, the actually output in function second display "first_var is not defined"
I am confused, could some one give me some explanation?
Thanks in advance.
Scoping is based in the lexical structure of the code, not the dynamic runtime relationship between functions (the "thread of execution"). The lexical structure is the static organization of the code; the "nesting" of function inside function.
In your case, the "second" function is declared outside of the "first" function, so the local variable in "first" is not visible to the code in "second".
If you were to move the "second" function inside "first":
function first() {
function second() {
var second_var = 'b';
console.log(first_var);
console.log(second_var);
}
var first_var = 'a';
second();
}
then the variable would be visible.
JavaScript has two scopes: global and function. (ES6 will introduce block scope with let and const, but for the sake of discussion, just assume the first two.
What this means is that variables defined in a function are only visible within that function. This has nothing to do with execution context.
So, in your example, first_var is only visible in first, second_var is only visible in second, global_var is visible globally because its not defined in a function.
Execution context comes into play with how this is defined, but that is another question and another topic entirely.
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.