How Javascript works in memory? - javascript

Hey everyone i got a question about how Javascript works in memory
i've heard that every execution context has a space in memory for that execution context
so if that so that's mean that all the variables on the program doesn't sits randomly in memory but rather sits in a memory block of the execution context where they created
now i will try to explain it visually
let's say we have a program and inside that program we have a function called createVars
function createVars(){
var name = 'John',lastName = 'Doe',age = 24;
}
when we invoke the createVars function it will create a new execution context and that execution context will have it's own block in memory where it now reserved for that execution context variables and the this keyword and the outer reference
so here is an example let's say we have an unoccupied place in memory
and now we invoke createVars()
does it look like that in memory or the variables are randomly placed ?

Related

Safe code in javascript How it handles the global execution context

This might be a silly question but most of the frameworks start with
(function(){
//all data
})()
Immediately invoked expression
So that There will be no collision with other js files right,so basically this is a function execution context that gets popped of the stack after execution,
but how come it still could handle asynchronous requests like a click after page has been loaded
For example:
(function(){
//all data
var a=true;
btn.addEventListener("click",()=>{
alert(a);
});
})() ;
The whole code runs first and an event Listener is given to a button but after,that execution context is popped off the stack so how come my button can still contact and get data from the "finished safecode function"?
Is this an implementation of closures where execution stack gets popped off but still the variables needed for dependant nested functions getting hung up?
Yeah, that's just the behavior of closures: a function always has access to everything declared in its outer blocks (lexical scope), even if the outer blocks have already finished execution. Until those functions don't exist anymore, the variables will continue to exist.
Inner functions keep a reference of their parents execution context

Are JavaScript execution contexts and JavaScript objects the same thing from a logical point of view?

My understanding of JavaScript is that on script execution a global execution context is created - what I understand to be a series of key:value pairs in reserved memory space - much like a regular JavaScript object.
On function execution, a new execution context is created with access to the 'parent' execution context. This seems (to me) at least to be the equivalent of re-initializing the JavaScript execution environment. Except that non of the key:value pairs initially set up in the global object need to be added to the new execution context since the child execution context has access to the parent's key:values pairs.
So for example:
function Y() {
this.prop = 4;
};
Y.prototype.doY = function() {
console.log(this.prop);
};
function X(){
this.prop = 5;
this.y = Object.create(Y.prototype);
Y.call(this.y);
};
// I can instantiate the object like so:
var x = new X();
// Which is equivalent to the following:
var x = Object.create(X.prototype);
X.call(x);
// Then I can add a function to the object that the X constructor points to via the X.prototype reference:
X.prototype.doX = function() {
console.log(this.prop)
};
// And then i can execute doX() in the context of the x object
x.doX(); // 5
x.y.doY(); // 4
On execution, doX function creates an execution context referenced from within the x object. The x object in turn is referenced within the global object.
Likewise, on execution the doY function creates an execution context that is referenced from within the x.y object.
It seems to me that an execution context as created by function execution is basically equivalent to a JavaScript object from a logical point of view:
Both allow for variable declaration NOT visible to parent objects/execution contexts
Both contain some kind of internal reference to parent object/execution context
It seems that both objects and execution context are just a list of key:values, the whole list being referenced by a single (ONLY a single) parent object (i.e. the y object exists as a reference within the x execution context) - or the global object as the root parent object (the x object exists as a reference within the global execution context).
So the question is: Is JavaScript execution context the same as a JavaScript object? If not, what is the difference?
This question: Are Execution Context and Variable Object actually same thing in JavaScript? mentions that in terms of implementation, that an execution context and an object are NOT the same thing.
Would it be correct to say that execution context inherits from Object? Or is implementation of objects/execution contexts completely non-related... One difference that I can see is that on creation, an execution context is 'processed' from top to bottom (lexically speaking) allowing an author to specify imperative commands - i.e. instruct the computer to do things. But in terms of architecture, this difference seems like an extension of the idea of an object rather than something completely different.
It seems to me that a 'running JavaScript environment' if such a thing exists, is basically a tree. The root node is the global execution context, and creating object adds nodes to the root node, or (as in the case of y above), adds nodes to the child nodes. Child nodes then reference parent nodes via a property to allow for scoping to parent execution context.
Then in terms of closures, which involve creation (and execution) of an execution context, on return the resultant object seems EXACTLY like a regular object since the 'execution context' as referenced by the closure will never again be executed (i.e. the same function, re-executed would create a new execution context and closure).
So from an "applied" point of view, is there ever a time that this -> i.e. a self reference to the current execution context, is NOT the same as the object from which a function call is made (aside from when using call, apply, or bind)? i.e. in the case of x.y.doY(), the function doY is called from the x.y object.
Execution contexts are conceptually objects, yes, as are several other things in the specification. That doesn't make them the "same" as JavaScript objects. They're a specification device and may not literally exist at runtime at all; code cannot directly reference them. For the full picture, read Executable Code and Execution Contexts in the spec.
Is JavaScript execution context the same as a JavaScript object?
No. A JavaScript object can be directly referenced by code, has a prototype, and has specific behaviors described for it which are not described for execution contexts, etc.
Would it be correct to say that execution context inherits from Object?
No, nothing in the spec suggests that to be the case.
It seems to me that a 'running JavaScript environment' if such a thing exists, is basically a tree.
Sort of, fairly indirectly. The spec doesn't describe any link from an execution context to its parent or child contexts. Instead, the lexical environment objects which are part of the context's state (specifically the LexicalEnvironment and VariableEnvironment state components) have a link to their parent lexical environment for the purposes of binding resolution. (The parent lexenv doesn't have a link to its children in the spec.) But they, too, are purely a specification device which may not literally exist at runtime and cannot be directly referenced by code.
So it's absolutely correct to think of them as objects, that's how the spec describes them, but they aren't JavaScript objects in the way that term is normally understood — something code can directly reference and act upon.
No, they are not the same thing. Not at all.
First, you seem to be confusing execution contexts with environment records. The former are basically call stack frames, the latter ones store variable values and form a tree as you described. Let's talk about environment records.
Environment records feature a key-value mapping and a link to their parent environment. In that regard, they are similar to a JS object with its properties and prototype link indeed. In fact, in a with statement or the global scope a so called object environment record is backed by an actual JS object.
However, they are still very different. Most environment records are declarative, that means their shape is determined before they are used. They are like an object that is not extensible. Also they cannot have getter/setter properties. And they differ in many more minor details.
But most importantly, environment records are just specification type values. They "are specification artefacts that do not necessarily correspond to any specific entity within an ECMAScript implementation. Specification type values may be used to describe intermediate results of ECMAScript expression evaluation but such values cannot be stored as properties of objects or values of ECMAScript language variables." So no, they do not inherit from Object at all.
Your question seems to ask: what can execution contexts record do that cannot be recorded in javascript objects?
You've got well documented answers already. So my contribution will be practical examples.
How would you manage the following 2 examples from a key/value perspective:
// Execution context of anonymous functions
(function (x) {
var y = x+1;
console.log(y);
}) (1);
// Life cycle of objects versus reference
var x = {a:1};
var y = x;
x = {b:1};
console.log(y);
If you start inventing keys that are not in the code, you should realize that this approach is limited. And so, not working if you push beyond the limits.

JavaScript Scope and Execution Context

I am trying to understand JavaScript scope rules. What I have read in textbooks and the documentation is confusing.
It seems to me that JavaScript is a statically (or lexically) scoped language - when trying to bind a variable name to a variable (definition), the lexical structure of the code is used.
An execution context seems to be similar to a stack frame on the call stack. Each execution context has a variable object upon which all the local variables (of the associated function) are defined. These variable objects are linked together to provide a 'scope chain' from the variable object at the top of the stack to the variable object at the bottom of the stack (the window object). This scope chain is searched from top to bottom in binding variable names to variables. This is very similar to statically scoped languages like C/C++/Java.
There seems to be one important difference with respect to C/C++/Java -- it is possible to access a variable defined in a function whose stack frame is no longer on the call stack, as shown in the example below:
var color = "red";
var printColor;
function changeColor() {
var color = "green";
printColor = function(msg) {
alert(msg + color);
}
printColor("in changeColor context, color = "); // "green"
}
changeColor();
// stack frame for "changeColor" no longer on stack
// but we can access the value of the variable color defined in that function
printColor("in global context, color = "); // "green"
Have I got this right? Are there other issues I should be aware of?
Thanks in advance
This is indeed a major difference between C/C++ and JavaScript: JavaScript is
a reference-counted, garbage-collected language, which means that objects can
be reclaimed by the engine when they no longer have any references to them.
The function you assign to printColor isn't on the stack, per se, as it
would be in C or C++; it's allocated dynamically and then assigned to
a variable outside your current scope. So, when control flow returns from
changeColor, the anonymous function still has a reference count of 1
since the outer printColor refers to it, and thus it's usable from the outer
scope.
So, your example isn't so much of a scoping issue--it's clear that you declare
printColor outside of the function scope of changeColor. When you define
changeColor, it
closes the upvalue
printColor into the new function scope, making it accessible. Like
Combat said, if you add a var to the second, inner definition of
printColor, it'll
shadow the first
printColor you declared and it won't be accessible outside that function
block.
As far as other issues to be aware of, yes, there are quite a few, but see my
comment on your original post for a good start.
It always comes down to lexical scoping which is function are executed with its scope chain when it is defined, not when it is invoked.
The anonymous function is defined in the local scope of function changeColor instead of the global scope. Hence when it is executed again, it prints out the color green which is listed in the local scope of function changeColor.

What is the 'Execution Context' in JavaScript exactly?

My title pretty much sums it all.
Can anyone enlighten me on...
"What is the 'Execution Context' in JavaScript?"
and on how it relates to 'this,' hoisting, prototype chaining, scope and garbage collection?
You're asking about several different concepts that aren't very closely related. I'll try to briefly address each.
Execution context is a concept in the language spec that—in layman's terms—roughly equates to the 'environment' a function executes in; that is, variable scope (and the scope chain, variables in closures from outer scopes), function arguments, and the value of the this object.
The call stack is a collection of execution contexts.
See also this answer and this article.
Scope is literally that: the scope in which a variable can be accessed. Simplistically:
var x;
function a() {
var y;
}
x can be accessed from anywhere. When a is invoked, x will be in the outer scope. (Stored in the scope chain.)
In contrast, y can only be accessed by code in a() because it is limited to a's scope. This is what the var keyword does: restricts a variable to the local scope. If we omitted var, y would end up in the global scope, generally considered a bad thing.
Think of hoisting as more of a compile-time thing. In JavaScript, function declarations are "hoisted" to the top of their scope. In other words, they are parsed and evaluated before any other code. (This is opposed to function expressions, which are evaluated inline.) Consider the following:
a();
b();
function a() { }
var b = function() { }
The call to a() will succeed because its declaration was hoisted to the top; a was assigned to automatically before program execution began. The call to b() will fail with a TypeError because b will not be defined until line 4.
You have asked so many concepts but lets pick one by one & understand them.
The environment in which your code is running is Execution context.
It is created when your code is executed.
Execution Context (Global), created by JS Engine contains 3 important things for you:
Global object - window
Special Object this
Ref to outer environment
Lets see a simple example to understand Global Execution Context:
var a = "Hello World";
function b(){
}
When JS Engine runs this above code it creates following Execution context (shown in image):
Global Execution Context
Now let's see how JS Engine creates Execution Context (then we will dig out & understand hoisting):
consider this scenario:
b();
console.log(a);
var a = "Hello World!";
function b(){
console.log("Called b!");
}
I can call the function b() even though it is declared later.
This means JS Engine is doing something before my code is executed, lets see what:
JS Engine performs following two steps to while executing any code:
CREATION PHASE :
JS Engine parses - run through your code & identifies variables & functions created by code (which will be used in execution phase)
Setup memory space for Variables & Functions - "Hoisting"
Hoisting - before your code is executed, the JS Engine set asides memory space for Var & Func used inside the code.
These variables & functions comprise the Execution Context of any function that is be executed.
All variables in JS are initially set to undefined.
Execution PHASE: pretty simple to understand,
When the code is executed line-by-line (by JS interpreeter) it can
access the variables defined inside Execution Context
variable assignment are done in this phase
A new Execution Context is created whenever function invocation is there
Execution Context Stack:
What happens when you invoke a function:
function b(){
}
function a(){
b();
}
a();
Now first of all Global Execution Context is going to be created
(as explained above)
then execution starts and interpreeter encounters call to function
a(), and here a new execution context is created pushed on top EC
Stack
so anytime you invoke a function a new EC is created & placed on top of EC Stack.
so now EC for a() is CREATED interpreeter will execute the code
inside a() line-by-line
then intrepreeter encounters call to function b(), this creates
another EC which is pushed on top or EC stack
When b() finishes it will be popped-off the stack then a() will finish &
all the way down to Global EC
see Execution Stack for above code snippet
I have addressed only the topics that are most closely related.
Execution Context is the wrapper around your existing code; which contains code that you have not written; but is generated by the JS Engine.
It comprises of the following -
Global Object
'this'
Outer environment
Your code
An Execution Context is created each time you run your .js file/app. The first step in this creation phase is Hoisting. The JS Engine reserves space or set's up memory for all the variables and functions defined in your code. These are then accessed when your code is executed line-by-line.
For example:
b();
console.log(a);
var a = "hi!";
function b() {
console.log("calling function");
}
Here, the function b() and variable a are both accessed before they are defined, however, due to hoisting the console will not throw any error.
The output will look like - (try it)
calling function
undefined
Notice how the function was executed completely, but we have undefined for the variable. This is because Hoisting is performed differently for functions vs variables. The function as a whole is picked up into the memory, but for the variables, space is reserved as a placeholder with the value of undefined. The actual value is then replaced when the engine executes your code line-by-line.
I hope this clears the concept for you.
I would like to address
Context
this context (relation with context)
Scope
1 : Execution Context
JavaScript is a single threaded language, meaning only one task can be executed at a time. When the JavaScript interpreter initially executes code, it first enters into a global execution context by default. Each invocation of a function from this point on will result in the creation of a new execution context.
This is where confusion often sets in, the term execution context is actually for all intents and purposes referring more to scope and not context. It is an unfortunate naming convention, however it is the terminology as defined by the ECMAScript specification, so we’re kinda stuck with it.
Each time a new execution context is created it is appended to the top of the execution stack. The browser will always execute the current execution context that is atop the execution stack. Once completed, it will be removed from the top of the stack and control will return to the execution context below.
An execution context can be divided into a creation and execution phase. In the creation phase, the interpreter will first create a variable object (also called an activation object) that is composed of all the variables, function declarations, and arguments defined inside the execution context. From there the scope chain is initialized next, and the value of this is determined last. Then in the execution phase, code is interpreted and executed.
2 : this Context
What is “this” Context?
Context is most often determined by how a function is invoked. When a function is called as a method of an object, this is set to the object the method is called on:
var obj = {
foo: function() {
return this;
}
};
obj.foo() === obj; // true
The same principle applies when invoking a function with the new operator to create an instance of an object. When invoked in this manner, the value of this within the scope of the function will be set to the newly created instance:
function foo() {
alert(this);
}
foo() // window
new foo() // foo
When called as an unbound function, this will default to the global context or window object in the browser. However, if the function is executed in strict mode, the context will default to undefined.
3 : Variable scope
A variable can be defined in either local or global scope, which establishes the variables’ accessibility from different scopes during runtime. Any defined global variable, meaning any variable declared outside of a function body will live throughout runtime and can be accessed and altered in any scope. Local variables exist only within the function body of which they are defined and will have a different scope for every call of that function. There it is subject for value assignment, retrieval, and manipulation only within that call and is not accessible outside of that scope.
ECMAScript 6 (ES6/ES2015) introduced the let and const keywords that support the declaration of block scope local variables. This means the variable will be confined to the scope of a block that it is defined in, such as an if statement or for loop and will not be accessible outside of the opening and closing curly braces of the block. This is contrary to var declarations which are accessible outside blocks they are defined in. The difference between let and const is that a const declaration is, as the name implies, constant - a read-only reference to a value. This does not mean the value is immutable, just that the variable identifier cannot be reassigned.
For Other topics:
GC : GC
Prototyping : Prototyping
The "Execution Context" is an umbrella that wraps all of the code to help manage it. It's like a manager that manages any environment. Since there's so many lexical environments because in a JavaScript application you have lots of variables and functions you need a way to manage everything. What comes first, what comes second and so on, and if you did not have an "Execution Context" environment everything goes to hell. So consider the "Execution Context" a wrapper, a manager that manages your code.
When you execute a function you create a new execution context comprising a local memory which is called a variable environment and this which is a placeholder, it will refer inside its execution context to whatever is the left of the . where that function is being called upon.
what is EC(Execution context) in JS ?
Simply put, an execution context is an abstract concept of an
environment where the Javascript code is evaluated and executed.
Whenever any code is run in JavaScript, it’s run inside an execution
context.
For more depth details : https://blog.bitsrc.io/understanding-execution-context-and-execution-stack-in-javascript-1c9ea8642dd0
I suppose a simple example would explain everything.
Note: function.call(object) calls function function in context of object
// HTML
​<p id="p"></p>​​​​​​​​​​​​​​​​​​​​​​​​
// JavaScript
function helloWorld() {
alert("HelloWorld: " + this);
}
var p = document.getElementById("p");
helloWorld(); // HelloWorld: [object DOMWindow]
helloWorld.call(window); // HelloWorld: [object DOMWindow]
​​​​​​helloWorld.call("String"); // HelloWorld: String // Note: "toString()"
helloWorld.call​​​​(p); // HelloWorld: [object HTMLParagraphElement]
helloWorld.call(new Date());​​​​ // HelloWorld: Tue Feb 21 2012 21:45:17 GMT+0100 (Central Europe Standard Time)
Execution Context is a wrapper to help manage the code that is running.
In your code you will see lots of lexical environments (which means areas of the code between { ... }) but which one is currently running is managed via execution contexts. It can contain your code and it also can contain beyond what you've written in your code.

Using JavaScript closures in setTimeout

I'm using setTimeout to emulate rendering, and I came to the structure like this:
var Renderer = new Class (
{
Implements: Events,
initialize()
{
this.onRender();
},
onRender: function()
{
// some rendering actions
setTimeout(this.onRender.bind(this), 20);
}
});
Does that code have potential memory leaks because of infinite nesting of closures? Or everything is ok? The only solution I came so far is to rewrite it to usual
function Renderer()
{
var onRender = function()
{
// rendering
setTimeout(onRender, 20);
};
onRender();
};
But I don't want to lose Mootools Events and Classes.
For some reasons I can't use a "singleton" (like window.renderer = new Renderer();) too
Your code is fine, but Andy's answer is misleading because it confuses the scope chain with execution context and, by extension, call stack.
First, setTimeout functions do not execute in the global scope. They still execute in a closure and can access variables from outer scopes. This is because JavaScript uses static scope; that is, the scope chain of a function is defined at the moment that function is created and never changes; the scope chain is a property of the function.
Execution context is different and separate from the scope chain in that it is constructed at the time a function is invoked (whether directly – func(); – or as the result of a browser invocation, such as a timeout expiring). The execution context is composed of the activation object (the function's parameters and local variables), a reference to the scope chain, and the value of this.
The call stack can be thought of as an array of execution contexts. At the bottom of the stack is the global execution context. Each time a function is called, its parameters and this value are stored in a new 'object' on the stack.
If we were to change your onRender function to simply call itself (this.onRender()), the stack would quickly overflow. This is because control would never leave each successive onRender function, allowing its execution context to be popped off the call stack. Instead, we go deeper and deeper with each onRender waiting for the next onRender to return, in an infinite cycle broken only when the stack overflows.
However, with a call to setTimeout, control returns immediately and thus is able to leave the onRender function, causing its execution context to be popped off the stack and discarded (to be freed from memory by the GC).
When the timeout expires, the browser initiates a call to onRender from the global execution context; the call stack is only two deep. There is a new execution context – which by default would inherit the global scope as its this value; that's why you have to bind to your Renderer object – but it still includes the original scope chain that was created when you first defined onRender.
As you can see, you're not creating infinite closures by recursion because closures (scope chains) are created at function definition, not at function invocation. Furthermore, you're not creating infinite execution contexts because they are discarded after onRender returns.
We can make sure you're not leaking memory by testing it. I let it run 500,000 times and didn't observe any leaking memory. Note that the maximum call stack size is around 1,000 (varies by browser), so it's definitely not recursing.

Categories

Resources