Some Advanced Concepts in Javascript.

Some Advanced Concepts in Javascript.

In this piece I want to talk about three advanced JavaScript concepts: execution context, lexical environment, and closure.

In this piece I want to talk about three advanced JavaScript concepts: execution context, lexical environment, and closure.

This will be a long post. If you want to skip to the summary, scroll to the bottom of the page.

What is an Execution Context?

So, what is an execution context? Whenever you write some code, your code is in a space — that space is called the “execution context”. Imagine you wrote a simple calculator:

function cal(type, a, b) {
  if (type === 'add') {
    return a + b;
  } else if (type === 'subtract') {
    return a - b; 
  } else if (type === 'multiply') {
    return a * b; 
  } else {
    return a / b; 
  }
}

var four = 4;
var seven = 7;
cal('add', 4, 7);

In JavaScript, whenever a function is invoked, a new execution context is created on the execution context currently running. A newly created one is stored in the stack for execution contexts.

So, if we call cal(), the new context will be created and it will be pushed to the context stack. But, by default, there’s an already existing context in the stack — a global execution context.

First the function cal is called and run so the new execution context is created. Then it is stored in the context stack. Then the control of the current execution context is transferred to the newly created one from, in this case, the global context.

An execution context is created whenever you call a function. When developing in JavaScript, you might have seen this error:


Call stack error

The function a keeps calling itself recursively. Every time a calls itself, a new execution context about a will be created and stored in the stack. Since the memory stack’s storage space isn’t infinite, it overflows.

Now you know what an execution context is, but there is more to learn. We’ll talk about it further shortly.

A Lexical Environment

What happens when you run a function or when you declare a variable or a function? I barely explained that an execution context is created on every function calls and there’s a global execution context in the stack by default. An execution context is divided into three different areas.

The first two sections in an execution context — LexicalEnvironment and VariableEnvironment, are very similar, so I think I can call them just LexicalEnvironment. What LexicalEnvironment does is to keep track of variables, function names and associated values. In other words, if you declare a function foo like a figure above, then the LexicalEnvironment would look like this:

function foo() {
  var a = 10;
  function bar() {
    
  }
}
foo();

// When foo is called, a new execution environment 
// might look like this below
execution_environment: {
  LexicalEnvironment: {
    a: 10,
    bar: function() {}
  },
  ThisBinding: ...
}

You now know what LexicalEnvironment is and what it does.

Just as an execution context consists of three parts, LexicalEnvironment also consists of a few parts. It has anEnvironmentRecord — I will call it an environment record, and an outer lexical environment that you may think it’s scope.

When you declare a variable or a function, they are actually stored in its environment record. Chaining the value of property basically means chaining the value of a property that belongs to an environment record.

A reference to the outer lexical environment is also created when LexicalEnvironment is created. It directly links to the parent LexicalEnvironment, and JavaScript uses this value when it can’t find a property in the current LexicalEnvironment. If it still can’t find it in the parent LexicalEnvironment, then it, again, goes up to the parent LexicalEnvironment. This process doesn’t stop until it finds what it’s looking for or until nothing is connected to the LexicalEnvironment. The global LexicalEnvironment doesn’t have a parent's LexicalEnvironment. So, when JavaScript tries to look for something in the global LexicalEnvironment, a Reference Erroroccurs.

Example with figures

To understand this flow better, let’s take a look at this example:

var x = 1;
function foo() {
  var y = 2;
  function bar() {
    var z = 3;
    function baz() {
      console.log(z);
      console.log(y);
      console.log(x);
      console.log(w);
    }
    baz();
  }
  bar();
}
foo();
// 3
// 2
// 1
// Reference Error: w is not defined


The global LexicalEnvironment

When JavaScript runs the code, the variable x and the function foo are declared in the global LexicalEnvironment. As I explained, the global’s outer doesn’t point to anything. When JavaScript meets foo() , it runs the function and the newLexicalEnvironmentoffoois created. Its outer link links to its parent’s globalLexicalEnvironment. This figure illustrates the whole relationship in the example code:


The entire relationship amongst LexicalEnvironments

You can see outer in each LexicalEnvironment points to the parent’s LexicalEnvironment.

When baz() is called, it looks for z, y , x , and w.


The workflow when z and w are looked for

Like this flow, finding the variable y and x does the same work — checking whether or not to exist the value in the current LexicalEnvironment and moving to the parent’s one if there’s no variable. But for w , it doesn’t exist anywhere in the codes so we end up with a reference error.

This is what you normally heard, a scope chain. But remember, the outer environment, connecting to the parent’s environment, is determined when the function is declared, not when it’s invoked (Click here to get further information). For instance, guess the return value of bar().

var x = 1;
function foo() {
  var x = 2;
  bar();
}

function bar() {
  console.log(x); 
}

foo(); // 1

Why is the result of foo() 1 and not 2? As I said, the outer reference is the parent’s LexicalEnvironment, not the function surrounding it.

ThisBinding

The reference inside the execution context, ThisBinding, determines how the function is called. I’ll talk about this topic more in another piece.

Back to Execution Context

Now, you know what are in an execution context — LexicalEnvironment and ThisBinding. There are actually two kinds of execution context — global execution context and function execution context.

The global execution context is the execution context for the global object in JavaScript, which is the root of everything. What it contains are several objects. One of them is window — when JavaScript parses and interprets your script, it actually runs this first. (Of course, this is not exactly how JavaScript works).

<script>
  window = {
    ClipboardCopyElement: class ClipboardCopyElement,
    CodeMirror: f Ea,
    DetailDialogElement: class DetailDialogElement,
    ...
  };
  
  GlobalExecutionContext: {
    LexicalEnvironment: {
      window: window,
      outer: null
    },
    ThisBinding: window
  }
</script>

That’s why you could use window.document or window.setTimeout, since they are all in the LexicalEnvironment of the global object.

What about a function execution context? It’s just like a global execution context but no window or other global objects exist inside and it is created when a function is called. What the global execution context and function execution contexts have in common is that they both have two phases at runtime: creation and execution phases. In the creation phase, variables and functions are declared:

var x = 1;
function foo() {
  var x = 2; 
  function bar() {
    var x = 3; 
  }
}
console.log(y);
var y = 3;

foo();

The first step on running the code is that the global execution context is created. The control of action is in the creation phase.


The creation phase

In the creation phase, variables are set by undefined by default. functions, on the other hand, are assigned by a function — like foo in the example above. The thing to note is that y is also defined as undefined as well, even though it’s declared after console.log . This symptom is called “hoisting” in JavaScript. Hoisting means variables and functions are declared and assigned with the default value, normally undefined , before the execution phase.

When the control moves to the execution phase, it runs every piece of code from the top. The first statement that will be executed is console.log(y) and it prints undefined out. Then y is set to three. The next step is to run foo(). When a function is called, a new execution context is created and pushed into the call stack.


The creation phase for a function

When a function is called, a function execution context is made. Then its creation phase starts first. The LexicalEnvironment of the function execution context defines all of the variables it needs. The special object, arguments, is a part of variables that are defined in every function LexicalEnvironment. You can see there’s a function bar(). Then the bar is invoked — its execution context will also be stored in the stack after being created.

Once all of the codes in a function are executed, its execution context is removed from the stack.

In this video, the speaker does a good job explaining the workflow of execution context switching in JavaScript.

Closures

I explained that LexicalEnvironment also has an outer environment that refers to the parent’s LexicalEnvironment. Take a look at this example:

var x = 1;
function foo(y) {
  return function(z) {
    return x + y + z;	
  }
}

var f = foo(2);

If you run this command on the web console, you’ll see this:

console.dir(f);



On above is what you can see from the google console and under is what you can see from the JavaScript Visualizer — the web page you can see here.

So, what happened? When the function foo was executed, it returned a new function. f now has the return value of foo . But in f , there’s a new scope object, named Closure. Even though the execution context of foo was removed from the stack, the referencing chains are still alive by the variable f . Then what if we execute f , now which is a function?

f(5);


Then the new execution context will be created like the picture above. The reason why z isn’t in the closure scope, is because it’s a property of the function that f ran, which is alive in the current execution context.

Once return x + y + z; is run and the function is finished, the execution context for f will be gotten rid of, and the closure will also be gone.

MDN defines closure:

A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function’s scope from an inner function.

Closure is a function that allows you to access to the parent function scope, even though it’s been removed from the execution context stack.

Final Summary

That was a long story to explain what execution context, LexicalEnvironment, closure, etc. Basically, when JavaScript runs codes, it creates a space for storing and managing variables and functions. It keeps track of the names and changes. Whenever a function is created, JavaScript makes this spaceand puts it on the top of the stack, where previously existing those spaces are stacked from the bottom. This space is called the execution context.

There are two execution contexts in JavaScript — the global execution context and the function execution context. An execution context is consist of LexicalEnvironment and ThisBinding. LexicalEnvironment is the place where variables and functions are actually stored and managed. ThisBinding is the reference for thisbut we didn’t cover that here.

JavaScript has two phases when it comes to managing variables and functions — creation phase and execution phase. During the creation phase, variables are declared but set by the default value, normally undefined, while functions are declared and initialized at once. After the creation phase, the action control moves to the execution phase, where all of the codes are executed, one by one, from the top of the file. If a function is invoked during this phase, a new execution context for that function will be created and stored in the stack. If there are too many contexts in the stack, we also confirmed that reference errors occur.

Even though an execution context is deleted from the stack once it has run all the codes inside, a reference to the function is alive when the original function returns a new function that uses a variable out of its scope. Then, the link to the outer function won’t be deleted until its codes are executed and completely removed from the stack. This is called Closure. Closure is a function that allows you to access the parent’s function scope, even though its execution phase is finished.

Angular 9 Tutorial: Learn to Build a CRUD Angular App Quickly

What's new in Bootstrap 5 and when Bootstrap 5 release date?

What’s new in HTML6

How to Build Progressive Web Apps (PWA) using Angular 9

What is new features in Javascript ES2020 ECMAScript 2020

Programming a Javascript Simon Game Tutorial

Programming a Javascript Simon Game Tutorial

In this javascript tutorial, I recorded myself live programming an html5 javascript simon game.

In this javascript tutorial, I recorded myself live programming an html5 javascript simon game.

For those who don't know, I'm a full stack web developer who has been in the industry for over 5 years now. There is a lot of things I have learned along the way and I'd like to share that knowledge with anyone wanting to learn!

like this video if you found it useful and would like to see more videos of the same content.

subscribe to my channel if you are trying to improve your abilities as a web developer, software engineer, or even if you are just learning to code.

Don't forget to turn on those bell notifications!

Understanding Memoization And Dynamic Programming in Javascript

Understanding Memoization And Dynamic Programming in Javascript

In this Javascript tutorial I will explain what memoization is, how to use it, when you should use memoization, how to use memoization, what dynamic programming is, how to use memoization in dynamic programming. Memoization is a big complicated word that you may have never even heard before, but you may be surprised to know that you are most likely already using memoization without even realizing it.

Memoization is a big complicated word that you may have never even heard before, but you may be surprised to know that you are most likely already using memoization without even realizing it. Memoization is just the act of caching values so that they can be calculated quicker in the future. Memoization is really useful in all parts of programming, but where it is most useful is in dynamic programming. In this video I will explain what memoization is, how to use it, and why it is so useful especially in dynamic programming.

🧠 Concepts Covered:

  • What memoization is
  • When you should use memoization
  • How to use memoization
  • What dynamic programming is
  • How to use memoization in dynamic programming

JavaScript Programming Tutorial - Full JavaScript Course for Beginners

JavaScript Programming Tutorial - Full JavaScript Course for Beginners

JavaScript is the programming language of HTML and the Web. JavaScript is easy to learn. This tutorial will teach you JavaScript from basic to advanced. JavaScript Programming Tutorial - Full JavaScript Course for Beginners

Watch this JavaScript tutorial for beginners to learn JavaScript programming from scratch. 👍

⭐️Course Contents⭐️

01 | Introduction

Get an introduction from Bob, as he kicks off the course, sets expectations, and gives you a little guidance for the road ahead.

02 | Setting Up the Development Environment

See how to install Node and Visual Studio Code, and learn why you need each. Watch as Bob writes a first tiny line of code to make sure that the installation is ready.

03 | Basic JavaScript Syntax

Hear about the basics of the JavaScript syntax, including how JavaScript is executed, how to create a properly formed statement, and more.

04 | Variables

Learn what variables are and how to declare, initialize, set, and get values from them.

05 | Data Types

JavaScript works with data types differently than other programming languages do. Learn from Bob as he explains some of the most basic data types and how to determine the type held by a variable.

06 | Type Coercion and Conversion

Sometimes you need to explicitly convert the data type of a value into a different data type. Sometimes JavaScript will do this automatically for you. Bob explains how and why this happens.

07 | Expressions and Operators

Learn how to spot a well-formed expression and how to compose expressions through the combination of operators and operands.

08 | Arrays

Watch as Bob demonstrates how to use arrays, how to add/remove elements of an array, how to access elements of an array using the index, how to get the number of elements in an array, and more.

09 | Function Declaration

Get an introduction to functions, as Bob shows you one way to define a function, how to call the function, how to pass parameters into a function, how to return values from a function, and more.

10 | Function Expressions

Sometimes a function declaration is more than you need. Get details in this lesson, as Bob demonstrates how to use a function expression and how to create an immediately invoked function expression.

11 | Decision Statements

Learn how to add logic to your applications by testing conditions using if / else statements, switch / case statements, and the ternary operator.

12 | Iteration Statements

Watch as Bob introduces the For and While statements, which enable you to loop through lists of values and perform operations on them.

13 | Basics of Scope

Hear an explanation of the notion of the lifetime of variables and their reach into other code blocks, in this discussion of scope.

14 | Returning Functions from Functions

As a building block toward a more sophisticated approach to building JavaScript applications, see how you can return functions from functions.

15 | Object Literals

Objects contain properties and functions that describe attributes of the object and its behavior, respectively. Watch as Bob demonstrates how to create object literals.

16 | Module Pattern and Revealing Module Pattern

Learn how to introduce variables and functions without leaving an unnecessarily large footprint on the global scope.

17 | Closures

Closures allow developers to bind functions to their execution context, including variables, so you can build specialized versions of functions. Learn how closures work and how to create them.

18 | this Keyword

Get the details on the "this" keyword, which causes a lot of confusion for JavaScript developers. Listen as Bob explains what this mysterious object is and how to bend it to your will.

19 | Destructuring

See how to use destructuring, a new feature in JavaScript that allows you to unpack array elements or object properties in a concise syntax.

20 | String Template Literals

Learn about the new string template literal syntax to enable string interpolation, multi-line string formatting, and more.

21 | Regular Expressions

Working with string data, Bob explains how use regular expressions to determine such things as whether a string matches a specific pattern or whether an instance of the pattern exists in a string.

22 | Built-In Natives

Join Bob as he examines native, built-in JavaScript functions that return objects that box the primitive types in order to provide additional helper methods on your values.

23 | Constructor Function Calls with the new Keyword

Learn how constructor functions work, see how to make key distinctions in what they are, and find out why they’re helpful.

24 | Objects and the Prototype Chain

Moving past the absolute beginner matter, listen in as Bob explains how objects work in JavaScript and how you can create an object that is linked to another object.

25 | JavaScript Classes

Bob demonstrates how “syntactic sugar” works on top of the existing functions and prototype chaining to help JavaScript resemble more traditional object-oriented programming languages.

26 | Arrow Functions

The latest version of JavaScript added arrow functions, a shorthand syntax for creating functions. Watch as Bob demonstrates how to create them and shows where they’re useful.

27 | Truthy and Falsy Values

Listen is as Bob circles back to topics that are important (but didn’t easily fit into earlier topics) and looks at the odd way in which JavaScript evaluates certain expressions as truthy and falsy.

28 | null Type

Similar to the undefined primitive type, the null type represents a variable that has no reference to an object when one was expected. Hear an explanation of how and why we should think about nulls.

29 | Date Objects

No discussion of JavaScript would be complete without understanding the Date built-in native function which provides properties and methods for working with dates and times.

30 | String Methods

The built-in native String function provides several very useful methods for manipulating and evaluating strings. Watch Bob demonstrate how to use a few of the most useful ones.

31 | Array Methods

We’ve worked with arrays throughout this course. Now Bob takes a few minutes to show you some of the most useful methods provided by the Array built-in native function.

32 | Error Handling with Try Catch

See how to wrap a try/catch/finally statement around potentially problematic code to anticipate everything that could go wrong with it, and learn other error-handling tips.

33 | Understanding the Document Object Model

Watch Bob examine the web browser environment and how it creates an object graph of nodes that represent elements, their attributes, and text, plus how to properly attach your code to an HTML page.

34 | Working with DOM Nodes

Continuing from the previous video, Bob demonstrates a slightly more compelling example that helps us understand how to manipulate, create, and delete element nodes and attribute nodes.

35 | Course Conclusion

In this final video, Bob briefly adds some closing comments and well wishes. You can also optionally complete a survey to provide insight into how Microsoft can improve this course.

Thanks for watching

If you liked this post, please do share/like it with all of your programming buddies!

Follow us on Facebook | Twitter