I was learning JS and execution contexts. Also, I found out that there is a special execution context which is executed by default which is fglobal execution context. The question is "Is global execution context a function which is executed behind the scenes"?
It's not a function, it's an abstraction that holds certain information about the context within which javascript is running. It is set up by the javascript engine before it starts to execute any code so it is created by a "function behind the scenes", but it is not itself a function. In the browser, the globsal execution context will include various functions and objects (like the document object). In node on the server, it will be something different. It is closely related to the global scope, but execution context and scope are not identical. It's quite a complex subject, so you may want to read this for more information: https://codeburst.io/js-demystified-04-execution-context-97dea52c8ac6
Related
When javascript runtime finds setTimeout() method, it sends it to Event table. How does runtime know that setTimeout() is a WEB API? Does it first look for setTimeout() method in the current context and then if not found assumes it as a WEB API?
When javascript runtime finds setTimeout() method, it sends it to Event table.
JavaScript doesn't "know" or care what setTimeout does. :-) It's just that setTimeout is one of the functions defined in the host environment provided to the JavaScript engine by the host (the browser, in your example). When you use JavaScript to call the function, the function's implementation (provided by the host environment) is executed with the information you provide. It's the host, not the JavaScript engine, that knows what to do with the arguments you provide to setTimeout.
When the host (the browser or Node.js or whatever) needs to create a new runtime environment (for instance, for a window), one of the things it does is create an object to be the host-provided global object for that environment (more properly called a realm), including putting any properties on that object (like setTimeout) that provide host-defined features. It provides that object to the JavaScript engine via what the JavaScript specification calls the InitializeHostDefinedRealm abstract operation. When the JavaScript engine runs your code that uses setTimeout, it sees the identifier setTimeout and looks in the current execution context to see if setTimeout is defined there; if it isn't, the engine looks at the parent execution context, and so on, until it reaches the global execution context, which gets its globals from the host-provided global environment (in part; it also has other globals). So, having found the function matching setTimeout, the JavaScript engine calls that function — which runs the host-defined code for the function, which sets the timer.
So the JavaScript engine doesn't know what setTimeout does, just that there is a setTimeout function on the global object it got from the host.
In terms of identifying which function to run, it doesn't make any difference whether a function is built into the engine, or added at run-time (this fact is really useful, allowing functions to be "polyfilled" if the engine doesn't provide them).
When you write foo(), JS actually looks for a variable with that name (this unification of variables, properties, functions and methods is an unusual feature of JS). It looks for it first in the local scope, then in the parent of that scope, and so on up the "scope chain".
The last place it looks is the "global object", which in a browser is the window object. So if you define window.foo as a function, you can call foo() from anywhere that doesn't have its own function called foo in scope.
Built-in functions work just the same way: when the JS engine starts up, it (conceptually) defines a whole bunch of functions on the window object, with special implementations referring to internal operations in the engine rather than composed of JS code.
So when you call setTimeout, JS walks up the scope chain, and if it doesn't find anything else, will find the setTimeout function registered by the engine, and runs it. The engine then does whatever it wants to do with that - hopefully, something that complies with the behaviours described in the current ECMAScript standard.
I know the V8 is consist of Memory Heap and Call Stack
The execution context is located in the call stack.
Global variables exist in the global execution context, and local variables exist in each execution context.
The reference type identifier is also located in the execution context. Even though the actual data exists in the heap area
question 1
If so, is it correct to think that all identifiers are on the call stack because they are in the execution context?
question 2
Where will the real primitive data like 25 be?
Just Started learning about JS.
CASE-1 Please look at the below given image.
My Understanding for this behavior : JS interpreter on reaching line 9 which commands to execute function a(); will create a new execution context for function a (or we can say allocate memory in heap for execution context which is an object and point this to it, right ??). Now i know that interpreter will first go through the whole function body and will allocate space for variable declarations and function declaration, in the execution context created in heap. This is evident from the right side of the image where in local Scope we have a reference variable b to the lambda of function. And now after having a pass through whole function body interpreter will execute code. Now since we already have the function b stored in a's execution context (or a's execution context knows about b),it will execute it. (This is what hoisting is, right ??)
So far so good. But,
Now look at this image :
Now if according to my concepts which i mentioned above,
On right side inside Local we must have a variable b referencing to function lambda, but its not.
What am i missing ??
Is my concepts wrong ??
Is it because of Chrome console ??
Can you explain this behavior ??
CASE-2 : Ok Then i did another experiment to know the behavior of Interpreter :
In both of the above given images, we have space allotted to variable a referencing to lambda of function, in both cases. This is completely opposite behavior to case-1.
Can you explain this behavior ??
Small Request (If you can..): If you can use the terms stack/heaps/memory/execution context object/link/pointers instead of Lexical environment, scopes, closures, chain etc etc it will be much preferred since they all are quite confusing. Its easy for me to understand things using above mentioned terms.
Nothing strange here. V8 compiles JavaScript directly into machine code. As a result, unreachable code, such as function b, is removed when it is never referenced. This is a common property of almost every compiler.
What am i missing ?? Is my concepts wrong ?? Is it because of Chrome console ?? Can you explain this behavior ??
In this code snippet, which is different than the specific example of case-1, namely in that the call to b has been removed, the b function has been removed by the compiler. As a result, you do not see any reference to it in the debugger.
case-2
In your examination of case-2, you overlook the fact that the debugger is stopped in the wrong place to analyze the interior scope of function a. As a result, you see a in the debugging window and that is it.
Your understanding section
JS interpreter on reaching line 9 which commands to execute function a(); will create a new execution context for function a (or we can say allocate memory in heap for execution context which is an object and point this to it, right ??)
Not entirely.
line 9: execute function a() [correct]
create an execution context for function a [correct]
allocate memory in heap [incorrect]
execution context is an object [correct]
point this to it [incorrect]
The execution context is an object, however, the compiled function is a static function frame stored on the stack. The this binding is a separate value which does not reference the execution context, but instead provides an entrance for variable scoping.
Now i know that interpreter will first go through the whole function body and will allocate space for variable declarations and function declaration, in the execution context created in heap.
This is incorrect. As noted, the interpreter is working on compiled code. This code already has an established memory footprint. A pointer is created on the heap which points to the compiled code in the stack.
This is evident from the right side of the image where in local Scope we have a reference variable b to the lambda of function.
b is not a lambda function, that would have been var b = () => console.log('Hello i am B');, and would not have been hoisted. That aside, under the hood, a is just a nested context. b is also compiled, and its static reference is just a component of the already compiled a. Scoping and memory storage are two very different concepts.
And now after having a pass through whole function body interpreter will execute code. Now since we already have the function b stored in a's execution context (or a's execution context knows about b),it will execute it. (This is what hoisting is, right ??)
This code is direct, so the interpreter would create a pointer on the heap, and immediately execute the compiled code on the stack. a is executed, then inside of a, b is executed as noted above.
Hoisting is simply moving declarations to the tops of scopes for function declarations and var declarations, but not const or let. Hoisting simply makes your first example equivalent to this:
function a(){
function b(){
console.log('Hello i am B')
}
console.log('Heloo')
b()
}
a()
As I understand it, every time a JavaScript program begins running, the engine first creates an execution context, pushes this execution context into the call stack/execution stack, and then it creates a global object (window in the browser and global in Node) as well.
To create the execution context, the engine first goes through the creation phase, where it allocates space in memory for entire function definitions and variable declarations (hoisting). It maintains a reference to the outer scope (this creates the scope chain, but in the global execution context there isn't anything above it), and it also creates the this property within the execution context and sets it to the window object in the browser and module.exports in Node. Lastly, the engine then goes through the execution phase, where it executes the code line by line and assigns a value to each variable.
Am I right in differentiating the global execution context creation from the creation of the global object itself? I view both of them as operations that happen side by side but are not the exact same thing.
Yes, it's fair to say that the global context and the global object are separate concepts. One illustrating distinction is the this binding: a context defines what this refers to (in case of the global context: to the global object); whereas the global object has no property named "this".
At the same time, global context and global object are somewhat coupled insofar as local variables in the former are properties on the latter.
Note that "execution context" is mostly an abstract concept, that means an engine only has to behave "as if" it did what the spec describes. Chances are that high-performance engines will take certain shortcuts (e.g., optimized code might keep some local variables in registers or on the machine stack, never putting them into any context at all).
I am watching a course where the professor mentions a local execution context being created every time we execute a function created by ourselves (he does not says exactly that, however he does not mentions this when he explains external functions like setTimeOut or fetch). However what happens when we call an external function (like setTimeOut or fetch) does javascript creates a local execution context for this functions too? What I mean by external functions is functions not created by ourself but part of an API.
Most external functions for javascript are actually written in C, so they don't have a javascript execution context per se. However, they still have a stack frame, which is similar to what a javascript execution context is.