Advanced JavaScript

Master advanced JavaScript concepts including design patterns, performance optimization, and modern development practices.

advanced JavaScript 7 hours

Chapter 1: Advanced JavaScript Fundamentals

Chapter 1 of 15

Chapter 1: Advanced JavaScript Fundamentals

1.1 JavaScript Execution Context

Execution context is the environment where JavaScript code is evaluated and executed. Understanding execution context is crucial for mastering JavaScript.

Types of Execution Context:

  • Global Execution Context: Created when JavaScript code first runs. There's only one global context per program.
  • Function Execution Context: Created every time a function is called. Each function has its own execution context.
  • Eval Execution Context: Created when code is executed inside eval() function (rarely used).

Execution Context Components:

  • Variable Environment: Stores variables and function declarations
  • Lexical Environment: Stores identifier-variable mappings
  • This Binding: Determines the value of `this` keyword
  • Outer Environment Reference: Reference to the outer lexical environment
// Example: Execution context creation
function outerFunction() {
    let outerVar = 'outer';
    
    function innerFunction() {
        let innerVar = 'inner';
        console.log(outerVar); // Can access outer scope
        console.log(innerVar); // Can access own scope
    }
    
    innerFunction();
}

outerFunction();

1.2 Call Stack and Execution Flow

The call stack is a data structure that tracks function calls. When a function is called, it's added to the stack. When it returns, it's removed.

function first() {
    console.log('First function');
    second();
}

function second() {
    console.log('Second function');
    third();
}

function third() {
    console.log('Third function');
}

first();
// Output:
// First function
// Second function
// Third function
// Call stack: first -> second -> third

Stack Overflow: Occurs when the call stack exceeds its maximum size, usually from infinite recursion.

1.3 Hoisting Deep Dive

Hoisting is JavaScript's behavior of moving declarations to the top of their scope before code execution. Understanding hoisting prevents common bugs.

Function Hoisting:

// Function declarations are fully hoisted
sayHello(); // Works - function is hoisted

function sayHello() {
    console.log("Hello");
}

// Equivalent to:
function sayHello() {
    console.log("Hello");
}
sayHello();

Variable Hoisting:

// var declarations are hoisted but initialized as undefined
console.log(x); // undefined (not ReferenceError)
var x = 5;
console.log(x); // 5

// let and const are hoisted but in "Temporal Dead Zone"
console.log(y); // ReferenceError: Cannot access before initialization
let y = 10;

// const behaves similarly
console.log(z); // ReferenceError
const z = 15;

Class Hoisting:

// Classes are hoisted but not initialized
const instance = new MyClass(); // ReferenceError

class MyClass {
    constructor() {
        this.value = 10;
    }
}

1.4 This Keyword Mastery

The `this` keyword refers to the object that is executing the current function. Its value depends on how the function is called.

Global Context:

console.log(this); // In browser: Window object, In Node.js: global object

Function Context:

function regularFunction() {
    console.log(this); // In strict mode: undefined, Otherwise: global object
}

regularFunction();

Method Context:

const obj = {
    name: 'John',
    greet: function() {
        console.log(`Hello, ${this.name}`);
    }
};

obj.greet(); // "Hello, John" - this refers to obj

Arrow Functions:

const obj = {
    name: 'John',
    regularMethod: function() {
        console.log(this.name); // "John"
    },
    arrowMethod: () => {
        console.log(this.name); // undefined - arrow functions don't have their own this
    }
};

obj.regularMethod();
obj.arrowMethod();

Explicit Binding:

function greet() {
    console.log(`Hello, ${this.name}`);
}

const person1 = { name: 'Alice' };
const person2 = { name: 'Bob' };

// call() - calls function with specified this and arguments
greet.call(person1); // "Hello, Alice"

// apply() - similar to call but arguments as array
greet.apply(person2); // "Hello, Bob"

// bind() - returns new function with bound this
const boundGreet = greet.bind(person1);
boundGreet(); // "Hello, Alice"

Constructor Context:

function Person(name) {
    this.name = name;
}

const person = new Person('John');
console.log(person.name); // "John" - this refers to the new instance
← Previous
Next → Closures and Scope Mastery