Harshil Chovatiya - Day 12: Function Scope - Deep Dive

Harshil Chovatiya - Day 12: Functions - Deep Dive

Harshil Chovatiya - Day 12: Function Scope - Deep Dive

Harshil Chovatiya - Day 12

Introduction

Hi, I'm Harshil Chovatiya, and welcome to my exploration of JavaScript's function scope and closures. In this blog, we'll journey through various levels of understanding, from local and global variables to more advanced concepts like lexical scope and closures. Join me as we unravel the mysteries of JavaScript's inner workings.

Level 1: Local Variables

Variables declared inside a function are considered local to that function.

                    
                    
    function myFunction() {
        const localVar = "I'm local!";
        console.log(localVar); // This works
    }
    console.log(localVar); // This will result in an error
                    
                

Level 2: Global Variables

Variables declared outside of any function have global scope and can be accessed from anywhere in your code.

                
                
var globalVar = "I'm global!";
function myFunction() {
    console.log(globalVar); // This works
}
console.log(globalVar); // This also works
                
            

Level 3: Shadowing Variables

When a local variable has the same name as a global variable, it "shadows" the global variable within the function.

            
            
var shadowVar = "I'm global!";
function myFunction() {
    const shadowVar = "I'm local!";
    console.log(shadowVar); // This refers to the local variable
}
myFunction(); // Output: I'm local!
console.log(shadowVar); // This refers to the global variable
            
        

Level 4: Function Scope and Block Scope

Variables declared with `var` have function scope, while those declared with `let` and `const` have block scope.

            
            
function varExample() {
    if (true) {
        var localVar = "I'm function-scoped!";
    }
    console.log(localVar); // This works
}
varExample();
console.log(localVar); // This will result in an error with let/const
            
        

Level 5: Lexical Scope

JavaScript uses lexical scoping, which means functions are aware of the variables in their parent scopes, even if those parent functions have finished executing.

            
            
function outer() {
    const outerVar = "I'm from outer!";
    function inner() {
        console.log(outerVar); // Inner function can access outerVar
    }
    return inner;
}
const closure = outer();
closure(); // Output: I'm from outer!
            
        

Level 6: Function Closure

Closures occur when a function "remembers" its outer scope, even if it's executed outside that scope.

            
            
function makeCounter() {
    let count = 0;
    return function() {
        return count++;
    };
}
const counter = makeCounter();
console.log(counter()); // Output: 0
console.log(counter()); // Output: 1
            
        

Level 7: Immediately Invoked Function Expressions (IIFE)

IIFEs are functions that are executed immediately after being defined.

            
            
(function() {
    const localVar = "I'm local and immediately invoked!";
    console.log(localVar); // This works
})();
console.log(localVar); // This will result in an error
            
        

Level 8: Module Pattern

You can use function scope and closures to create private variables and encapsulate code.

            
            
const myModule = (function() {
    const privateVar = "I'm private!";
    return {
        getPrivateVar: function() {
            return privateVar;
        }
    };
})();
console.log(myModule.getPrivateVar()); // Output: I'm private!
console.log(privateVar); // This will result in an error
            
        

Level 9: Recursion

Recursion is a programming technique where a function calls itself to solve a problem.

            
            
function factorial(n) {
    if (n === 0) {
        return 1;
    }
    return n * factorial(n - 1);
}
console.log(factorial(5)); // Output: 120
            
        

Level 10: Callback Functions

Callback functions are functions passed as arguments to other functions and executed later.

            
            
function doSomething(callback) {
    console.log("Doing something...");
    callback();
}

function callbackFunction() {
    console.log("Callback function executed.");
}

doSomething(callbackFunction);
            
        

Level 11: Promises

Promises are used for asynchronous operations and provide a cleaner way to handle callbacks.

            
            
function fetchData() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve("Data fetched successfully");
        }, 2000);
    });
}

fetchData()
    .then((data) => {
        console.log(data);
    })
    .catch((error) => {
        console.error(error);
    });
            
        

Level 12: Async/Await

Async/Await is a modern way to work with asynchronous code, making it appear more synchronous.

            
            
async function fetchData() {
    try {
        const response = await fetch('https://api.example.com/data');
        const data = await response.json();
        console.log(data);
    } catch (error) {
        console.error(error);
    }
}

fetchData();
            
        

Outro

As we wrap up this deep dive into function scope and closures, I hope you've gained valuable insights into how JavaScript handles variable scope and the power of closures. These concepts are fundamental to writing efficient and maintainable JavaScript code. I encourage you to continue practicing and applying what you've learned to your own projects. Thanks for joining me on this journey!

Social Media

Comments