Section 2: Execution Contexts and Lexical Environments

Syntax Parsers: A program that reads your code and determines what it does and if its grammer is valid. In other words, it's when programs, interpreters and compilers actually read your code, determines if the code is valid, and implements that syntax in a way that the computer can understand.

Lexical Environments: Where something sits physically in the code you write and what's around it. In other words, in programming languages, where you decide to write your code is very important.

Execution Contexts: A wrapper to help manage the code that is running. The wrapper can contain things beyond what you've written in your code.

Global: means not inside a function.

Creation Phase a.k.a. Global Execution Context when running code at the base level, the JS engine will automattically do the following:

  1. Creates a global object. Your code will sit inside of this global object.

  2. Creates a special variable called, "this". At the global level, "this" would equal the Global (window) Object.

  3. A reference or link to the outer environment if there is one.

  4. Hoisting, which setups up functions and creates a list of variables (but sets them all to "undefined"). Example code is below.

  5. Then JS will run your code line by line (which includes adding values to variables, thus replacing the "undefined".

Name/Value Pair: A name which maps to a unique value. And a value can be more name/value pairs. Those are called objects.

Object: A collection of name/value pairs.


Code Example 10-01

Consider the following code:

var a = 'Hello World';
function b() {
  console.log('Called b!');
}

b();
console.log(a);

console.log would report:

Called b!
Hello World

Now what if we did this?

b();
console.log(a);

var a = 'Hello World';
function b() {
  console.log('Called b!');
}

console.log would report:

Called b!
undefined

What happened? JS engine will sweep through your code in this order:

  1. Stores every function to memory, in their entirety.

  2. Stores every variable names to memory, but not the value! Instead JS will set a placeholder called undefined.

  3. JS engine will begin executing every line of code, which includes assigning values to variables.

This process is called hoisting.


undefined is more like a placeholder. JS is saying, "I'm going to set some memory aside for when you decide to place a value here."

Single Threaded: means one command is being executed one line at a time. JS behaves in a single threaded manner.

Synchronous: means one at a time. JS executes in a certain order, one line at a time. In JS, one thing is happening at a time.


Function Invocation and the Execution Stack

Invocation means running (or calling) function. As in, "Hey, run the function." We do this by using parenthesis, which will, invoke the function.

What happens when you invoke a function? Consider the following code:

function a() {
  b();
  var c;
}

function b() {
  var d;
}

a();
var d;

Every time a new function is called, a new execution context is created. After Global Execution Context is created, the code above will run in this order, line by line:

  1. a();

  2. Which runs function a()

  3. Within function a(), it takes a detour to function b();

  4. function b() is executed, then returns to finish up function a().

  5. function a() is complete, then finally we get to var d;


Function, Context, and Variable Environments

Variable Environment: where the variable lives. Consider the following code:

function b() {
  var myVar;
  console.log(myVar);
}

function a() {
  var myVar = 2;
  console.log(myVar)
  b();
}

var myVar = 1;
console.log(myVar)
a();
console.log(myVar)

Here's the path:

  1. var myVar = 1; is recorded first.

  2. Execute function a() which record myVar = 2;.

  3. Still inside function a(), we bounce to function b();.

  4. Inside function b();, myVar is undefined.

  5. We're back outside of the function scope where var MyVar still equals 1.

In the console.log, you should see:

1
2
undefined
1

The Scope Chain

What console.log do you expect to see with the following code:

function b() {
  console.log(myVar);
}

function a() {
  var myVar = 2;
  b();
}

var myVar = 1;
a();

You will get: 1. But why? Each function has an outer reference based on the lexical location where the function is written. If a variable is not defined within a function, myVar will look for it's value in the outer reference, and keep digging out until it reaches the Global Execution Context. This act of searching is called the Scope Chain.

Consider this code. What will console.log report?

function a() {
  function b() {
    console.log(myVar);
  }
  var myVar = 2;
  b();
}

var myVar = 1;
a();

Console log would return: 2

function b() sits lexically, or physically, inside of function a(). function b()'s outer reference is function b() and that us where myvar found it's value. So it stopped there.


Scope, ES6, And let

Scope: is where your variable is available in your code. And if it's truly the same variable, or a new copy.


What About Asynchronous Callbacks

Asynchronous: more than one at a time.

When a web page is loaded, simultaneous things are happening like JS creating the global stack, user events and HTTP requests. Events are saved in an Event Queue. After the stack is finished (or empty), the event queue (if any are relevant) are processed. That means any functions relying on a user event will be saved until the end.

results matching ""

    No results matching ""