Loading...

Go Back

Next page
Go Back Course Outline

JavaScript Full Course


Advanced JavaScript Concepts

Advanced JavaScript Concepts

1. Closures

Closures are functions that "remember" their lexical scope, even when the function is executed outside that scope. This allows powerful behavior such as data encapsulation.

Here’s an example of a closure:

function outerFunction(outerVariable) {
                          return function innerFunction(innerVariable) {
                            console.log("Outer Variable:", outerVariable);
                            console.log("Inner Variable:", innerVariable);
                          };
                        }
                        
                        const closureExample = outerFunction("I am outside!");
                        closureExample("I am inside!");

Output: The closure remembers the outerVariable even after the outer function has returned, allowing access to it inside innerFunction.

2. Currying and Partial Application

Currying is the technique of transforming a function that takes multiple arguments into a sequence of functions each taking one argument. Partial application refers to fixing a specific number of arguments to create a new function.

Currying Example

function multiply(a) {
                          return function(b) {
                            return a * b;
                          };
                        }
                        
                        const multiplyBy2 = multiply(2);
                        console.log(multiplyBy2(5));  // Output: 10

Output: The function is curried, meaning multiplyBy2 is a function that multiplies its argument by 2.

Partial Application Example

function multiply(a, b) {
                          return a * b;
                        }
                        
                        function partiallyApplyMultiply(a) {
                          return function(b) {
                            return multiply(a, b);
                          };
                        }
                        
                        const multiplyBy3 = partiallyApplyMultiply(3);
                        console.log(multiplyBy3(5));  // Output: 15

Output: Here, multiplyBy3 is a partially applied function that multiplies any given number by 3.


3. Higher-Order Functions

A higher-order function is a function that either takes one or more functions as arguments or returns a function. Higher-order functions are widely used in functional programming.

function mapArray(arr, transformFunction) {
                          const result = [];
                          for (let i = 0; i < arr.length; i++) {
                            result.push(transformFunction(arr[i]));
                          }
                          return result;
                        }
                        
                        const numbers = [1, 2, 3, 4];
                        const doubled = mapArray(numbers, (num) => num * 2);
                        console.log(doubled);  // Output: [2, 4, 6, 8]

Output: The mapArray function is a higher-order function because it accepts a function as an argument, which it applies to each element of the array.

4. Functional Programming Concepts

Functional programming (FP) emphasizes the use of pure functions, immutability, and first-class functions. Some important FP concepts include:

  • Immutability: Data should not be modified after it is created.
  • Pure Functions: Functions that return the same output for the same input and have no side effects.
  • First-Class Functions: Functions are treated as first-class citizens, meaning they can be assigned to variables, passed as arguments, and returned from other functions.

Pure Function Example

function add(a, b) {
                          return a + b;
                        }
                        
                        console.log(add(2, 3));  // Output: 5
                        console.log(add(2, 3));  // Output: 5

Output: This function is pure because it always produces the same output for the same inputs.

Immutability Example

const numbers = [1, 2, 3];
                        
                        const newNumbers = [...numbers, 4];  // New array, original array is not mutated
                        
                        console.log(newNumbers);  // Output: [1, 2, 3, 4]
                        console.log(numbers);     // Output: [1, 2, 3]

Output: The original array numbers remains unchanged, demonstrating immutability.


5. Garbage Collection and Memory Management

JavaScript automatically handles memory management through garbage collection, which removes unused objects to free memory. However, memory leaks can occur when references to unused objects are still present.

Garbage Collection Example

let obj = { name: "JavaScript" };
                        obj = null; // Now the object is eligible for garbage collection

Output: The object { name: "JavaScript" } is no longer referenced and will be cleaned up by the garbage collector.

6. Performance Optimization Techniques

Optimizing performance is crucial, especially for handling events like scrolling, resizing, or user input. Common techniques include debouncing and throttling.

Debouncing Example

let debounceTimer;
                        function debounce(func, delay) {
                          clearTimeout(debounceTimer);
                          debounceTimer = setTimeout(func, delay);
                        }
                        
                        window.addEventListener('resize', () => {
                          debounce(() => {
                            console.log('Resized!');
                          }, 500);
                        });

Output: The "Resized!" message will only be logged once after the user has stopped resizing for 500 milliseconds.

Throttling Example

let throttleTimer;
                        function throttle(func, limit) {
                          if (!throttleTimer) {
                            throttleTimer = setTimeout(() => {
                              func();
                              throttleTimer = null;
                            }, limit);
                          }
                        }
                        
                        window.addEventListener('scroll', () => {
                          throttle(() => {
                            console.log('Scrolling!');
                          }, 1000);
                        });

Output: The "Scrolling!" message will only be logged once per second, no matter how many times the user scrolls.

Go Back

Next page