Javascript Call Stack / Execution Context reference - javascript

When I executed the following javascript, I was expecting b()'s console log to print undefined. (Since I did not declare name).
function b(){
console.log(name);
}
function a(){
var name = "rupesh";
b();
}
var name = "Demo";
a();
Expected Output: Undefined
Actual output: Demo
I've been reading on Global execution context, Execution context of Javascript. It's been mentioned that the execution context will look for Global execution context.
But if i understand right, function a() and function b() are executed in a stack. How does it go back to execution context (In datastructure perspective this doesn't happen).
Kinda confused. Please explain how this works!

When I executed the following javascript, I was expecting b()'s console log to print undefined. (Since I did not declare name).
Technically name is declared. That's so called hoisting. So, the runtimer "catch" all the var declarations and put them on top of the function (in your case, as it's not inside a function, they're attached to the global namespace). So, it'd be like this:
var name;
function b(){
console.log(name);
}
...
Now, when a() is called the name variable has value assigned, in this case "Demo".
Inside function a () {...} you assign a variable called name again, but as this has var before it, that name doesn't change the global name (I think you have already figured that out, since you'd expected name to be undefined).
Finally, when b() is invoked inside a(), it looks to the global name variable assigned with the "Demo" value.
Just to show the whole picture, that's how the runtime "sees" your code:
var name;
function b(){
console.log(name);
}
function a(){
var name = "rupesh";
b();
}
name = "Demo";
a();

Related

Why execution context of function B doesnt pass its activation-object into function A-s scope-chain-object, that A has acces to variables of B

Hy guys thanks for reading my question. So I am researching this problem since 2 days and didnt find any answer, so thanks for helping. So here is the below code:
function A(){
console.log(myVar);
}
function B(){
var myVar = 2;
A();
}
B();
So here if I run this code, from function A will get an error massage: "myVar is not defined", because it doesnt have access to the variables of function B and this is what I dont udnerstand.
So as far as I know when the code starts to run, the global execution context will be created by the javascript engine and each time the engine hits a parentheses for function call - and some other conditions are met- , javascript creates an execution context object for the function which has been called.
It should include and the scope chain, the activation object and the "this" keyword and In the scope chain should be all the variable/activation objects of the parent execution contexts
So with otherwords function A in its scope-chain-object should have function B-s all variables (but obviously it is not the case and this is what I dont understand).
But if I run this code, where function A-s definition is nested in function B:
function B(){
var myVar = 2;
A();
function A(){
console.log(myVar);
}
}
B();
So now function A will have access to the variables declaired and initialized in function B.
But in my head it shouldnt matter, where function A have been defined since it has been called in the context of function B.
Even when the this keywords value is defined in the creation phase, its value will based on, where and how the function is called, not where it has been defined.
Thanks guys that your read threw my tons of words, I really appriciate it.
And thanks for every answer or any kind of article or matterial, that could help me understand this anomaly.
Cheers and thanks a lot.
In JavaScript a Lexical Environment of a function is called lexical because it is determined by the static structure of a program, not where the function is called from. It means that the outer Lexical Environment of the function A() will be the environment within which the function A() is declared, not called.

JavaScript Scope: Global Variable Confusion

I am having trouble understanding why the following code prints 1 and not 10. I thought that console.log would print 10 because if a variable is not declared within a function it is part of the global scope.
If I remove the line, function a(){}, the console.log statement prints 10. Can someone please explain why the presence of this line affects the value of a.
Additionally, if this question can be refined I would appreciate any suggestions
function b() {
a = 10;
return;
function a(){}
}
var a = 1;
b();
console.log(a);
Just add console.log(a); to your function and you will realize that 'a' is a function that has local scope, which means, it inside function b() and can't really be called from outside. Hence, the value of a remains as 1, as nothing really affects it.
function b() {
console.log(a);
a = 10;
return;
function a(){}
}
var a = 1;
b();
console.log(a);
Function declarations create local variables, and all declared variables are hoisted to the top of their containing function scope. Thus, you have something equivalent to:
function b() {
function a(){}
a = 10;
return;
}
which is in turn roughly equivalent to
function b() {
var a = function(){}
a = 10;
return;
}
As you can see in this form, it's clear that a is a local variable, so a = 10 assigns a value to the local a, not the global a.
Because both function declarations and variables are treated similarly under the hood.
When a function is called, its contents are first parsed to configure the stack frame ready for its execution.
As part of this process, function declarations and variables are inserted as identifier/value pairs into the same data structure (Environment Record inside the Lexical Environment) inside the stack frame (Execution Context) created when a function is called.
So by declaring a function a inside b, you create an identifier named "a" in the Environment Record created for the call to b, shadowing a in the outer context.
So a in the outer context remains 1.

Why can't I access this particular variable when referencing its outer environment?

I'm learning about lexical scope and execution contexts in JS and came across a question.
My understanding of the keyword this may be limited, but I see that it references all variables in any function's current execution context.
Consider this example:
function b(){
console.log(this);
}
var myVar = 1;
b();
Here, I'll get a console log to myVar which will be assigned to the value 1.
Now for this example:
function a(){
function b(){
console.log(this);
}
var myVar = 2;
b();
}
var myVar = 100;
a();
When function b is called, I see a reference to myVar, which is assigned to 100. Why isn't there a reference to myVar as assigned to 2?
Doesn't 'this' refer to the current function's lexical environment? In this case, function b is enclosed in function a and not the global environment.
Your understanding of this is completely wrong.
The value of this depends (usually) on how the function was called. (See How does the “this” keyword work? for details).
If you are:
in a browser
your JS isn't running in strict mode (which it should be)
the function is called with no explicit context
… then this will be the window object.
Normally, when a variable is declared, it exists only in the scope in which it was declared. It is not a property of any object.
There is one exception:
When a variable is declared in the global scope (i.e. outside of any function or without let or var inside a function) then it also becomes a property of the window object.
The effect you are seeing is the combination of those two things.
b(); has no context, so this is window. var myVar = 100; is outside of any function, so is a global and thus a property of window.

Scope chain in Javascript and calling nested function within the global scope

Here is the example I want to be enlighten on (Something that doesn't actually works).
var myVar = 2;
function a(){
var myVar = 2;
function b(){
console.log(myVar);
}
};
a();
b();
This will output in the console: Uncaught ReferenceError: b is not defined.
As you can see I have a function named a with a nested function called b.
At first I thought I could invoke b outside a and get it working normally.
I thought that would work because at first I call the a function.
By doing that I had in mind the fact that the a function would be put on the execution stack and during its creation phase the b function defined inside would be set in the memory.
As this is in memory I thought I could then execute this outside the function. Which obviously doesn't work.
So my conclusion is the b function is indeed set into memory during the creation phase of the a function but once the a function has finished to execute, once it's popped of the execution stack, the b function gets popped off the memory at the same time.
Thus calling it (I mean the b function) within the global scope is impossible.
Am I right on this ?
You are complicating things unnecessarily by speaking about execution stacks, creation phases and such.
The explanation is very simple: you cannot call b because the spec says that b is out of scope at the site where you are trying to call it. That is all, end of story.
Your example would actually work if converted to PHP, which makes me think that perhaps this is where you got the idea from. But JS and PHP are different languages and the (IMO ridiculous) manner that PHP treats nested functions does not transfer over.
If you want to call b outside of a, you need to create a reference to it outside of a:
var myVar = 2;
function a(){
var myVar = 2;
function b(){
console.log(myVar);
}
return b;
};
var b = a();
b();
This however won't cause b to print the global myVar. It will still have access to the myVar inside the closure scope of a.

Javascript - outer reference of a function shows "not defined"

i have the following code:
function log(a) {
var b = 5;
a();
}
log(function(){
console.log(b);
});
When that anon function is executed at function log, I am getting "b is not defined". Well, It seems like that anon's outer environment reference isn't log's, as If it wasn't created inside of it so therefore it can't find that var. so where is it being created? on the global level? My initial thought was that those parentheses make the anon function created inside of log's.
Every time you call a function, assuming that you do not declare global variables (you didn't declared any), the scope is created for that function and what goes in that scope is determined not by where the function was called but by where it was defined. You can see that where you defined the anonymous function (in the call to log), the variable b is not in that scope that is why it's not available.
Let's rewrite your code:
function log(a) {
var b = 5;
a();
}
function logger() {
console.log(b);
}
log(logger);
You can see that your code and mine are doing the same thing, the only difference is that mine code doesn't have an anon function. They do not share common variables in their scopes.
Now check this out:
var b = 5;
function log(a) {
a();
}
function logger() {
console.log(b);
}
log(logger);
Now both log and logger share a common variable b in their scopes (log is not using b so if you check it in a debugger it will be undefined). As I say you don't determine scope by where function was called but by where and how it was declared.
In JavaScript scopes exists within functions. So your b variable is visible only within its scope - the anonymous function. If you want it to be visible outside the function then you can assign the variable to the global scope.
function log(a) {
window.b = 5;
a();
}
log(function(){
console.log(b);
});

Categories

Resources