Harshil Chovatiya - Day 12: Function Scope - Deep Dive
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!
Comments
Post a Comment