JavaScript - Execution Context(Scope Chain, Variable Environment, this Keyword)

Last Updated on: August 31, 2021 pm

JavaScript - Execution Context(Scope Chain, Variable Environment, this Keyword)

Scope Chain

Concepts

Scoping

How program’s variables are organized and accessed.

Where do these variables live?

Where to access certain variable or where not?

Lexical Scoping

Scoping is controlled by placement of functions and blocks in the code.

Scope

Space or environment in which a certain variable is declared.

There are:

  • Global Scope,
  • Function Scope,
  • Block Scope

Scope of a Variable

Region of our code where a certain variable can be accessed.

3 Types of Scope

Global Scope

Outside of any function or block.

Variables declared in global scope are accessible everywhere.

Function Scope

Variables are accessible only inside function, NOT outside.

  • Also called Local Scope

    Block Scope (ES6)

Variables are only accessible inside a block.

ONLY applies to let and const variables! - NO var !!!
Functions are also block scoped.

Scope Chain

Variable Lookup in Scope Chain

Scope has access to variables from all the parent scopes(outer).

Scope Chain only works upwards.

Example with Execution Context and Scope Chain

Note: third() cannot access variables b and c

- because b is in first() scope and c is in second() scope.

Variable Environment

Hoisting

Hoisting: Make some types of variables accessible/usable in the code before they are actually declared.

Behind the scenes: Before execution, code is scanned for variable declarations, and for each variable, a new property is created in the variable environment object.

Temporal Dead Zone

Why TDZ?

Makes it easier to avoid and catch errors - accessing variables before declaration is bad practice and should be avoided.

The best way to avoid it is get an error when attempting to access it.

Practice Hoisting

1
2
3
4
console.log(addArrow);  // ===> undefined 
console.log(addArrow(2,4)); // ===> addArrow is not a function

var addArrow = (a, b) => a + b;

Why console.log(addArrow(2,4)); shows addArrow is not a function?

Because addArrow itself is a var, then it gets undefined when trying to access before initialization, then addArrow(2,4) becomes undefined(2,4). –> TypeError

1
2
3
4
5
6
7
if(!numProduct) {
deleteShoppingCart();
}
var numProducts = 10;
function deleteShoppingCart(){
console.log("All Products Deleted!");
}

Output:

1
All Products Deleted!

Because we are trying to access a var before initialization, then got an undefined

The this Keyword

Special variable that is created for every execution context (every function). Takes the value of (points to) the ‘owner’ of the function in which the this keyword is used.

1
2
3
4
5
const calAgeArr = year => {
console.log(2001 - year);
console.log(this);
};
calAgeArr(1997);

Output

1
2
4
Window

Arrow function does not have its own this => returns the lexical this keyword.

1
2
3
4
5
6
7
8
9
const jonas = {
year: 1996,
calcAge: function () {
console.log(2018 - this.year);
console.log(this);
},
};
jonas.calcAge();

Output

1
2
22
{year: 1996, calcAge: ƒ}

Simply returns jonas object.

Argument keyword

1
2
3
4
5
6
const addExpre = (a, b) => {
console.log(arguments);
return a + b;
};

addExpre(1, 5, 9, 100);

Output

1
2
3
script.js:21 Uncaught ReferenceError: arguments is not defined
at addExpre (script.js:21)
at script.js:25

Arrow Function does not have argument keyword.

Primitives vs. Objects (Primitive vs. Reference Types)

Primitives

Stored in Call Stack

  • Number
  • String
  • Boolean
  • Undefined
  • Null
  • Symbol
  • BigInt

Objects

Stored in Heap

  • Objects literal
  • Arrays
  • Functions

Important

Not all variables declared as const are immutable

  • Only primitive const are immutable
  • Object const can be changed.
  • Because the object are stored in the HEAP and the value of the address in the CALL STACK is only an address reference in the HEAP.