1. Difference between var, let, and const keywords in JavaScript.
- 1.- var
- Scope: Function-scoped. A variable declared with- varis accessible throughout the function in which it is declared.
- Hoisting: Variables declared with- varare hoisted to the top of their scope and initialized with- undefined.
- Re-declaration: Can be re-declared within the same scope.
- Use Case: Legacy keyword, generally avoided in modern JavaScript due to its unpredictable behavior.
- Example: - function example() { if (true) { var x = 10; } console.log(x); // 10 (accessible outside the block) } - 2.- let- Scope: Block-scoped. A variable declared with - letis only accessible within the block (e.g.,- {}) in which it is defined.
- Hoisting: Variables declared with - letare hoisted but not initialized. Accessing them before declaration results in a- ReferenceError(Temporal Dead Zone).
- Re-declaration: Cannot be re-declared within the same scope. 
- Use Case: Preferred for variables that need to be reassigned. 
 - Example: - function example() { if (true) { let y = 20; } console.log(y); // ReferenceError: y is not defined } - 3.- const- Scope: Block-scoped, similar to - let.
- Hoisting: Variables declared with - constare hoisted but not initialized. Accessing them before declaration results in a- ReferenceError.
- Re-declaration: Cannot be re-declared or re-assigned. However, for objects and arrays, their properties or elements can be modified. 
- Use Case: Preferred for constants or values that should not be reassigned. 
 - Example: - const z = 30; z = 40; // TypeError: Assignment to constant variable. const obj = { name: "John" }; obj.name = "Jane"; // Allowed (modifying property) - Key Differences Summary- Feature - var- let- const- Scope - Function-scoped - Block-scoped - Block-scoped - Hoisting - Hoisted (initialized as - undefined)- Hoisted (not initialized) - Hoisted (not initialized) - Re-declaration - Allowed - Not allowed - Not allowed - Re-assignment - Allowed - Allowed - Not allowed - Use Case - Legacy code - Variables that change - Constants - Architectural Implications- Avoid - var: In modern JavaScript,- varis discouraged due to its function-scoping and hoisting behavior, which can lead to bugs and unpredictable code.
- Prefer - const: Use- constby default for variables that do not need reassignment. This promotes immutability and reduces side effects.
- Use - letfor Mutability: Use- letonly when reassignment is necessary, such as in loops or dynamic value updates.
- Block Scoping: Leverage block scoping ( - letand- const) to limit variable visibility and avoid polluting the global or function scope.
 - Example in Practice- // Bad: Using var var count = 10; if (true) { var count = 20; // Re-declares the same variable } console.log(count); // 20 (unexpected behavior) // Good: Using let and const let total = 0; const taxRate = 0.1; for (let i = 0; i < 5; i++) { total += i; // Re-assignment allowed with let } console.log(total); // 10 console.log(taxRate); // 0.1 (constant value) 
2. Describe the distinctions between asynchronous and synchronous programming. What pattern does JavaScript follow?
- Synchronous: Code executes sequentially, blocking further execution until the current operation completes. 
- Asynchronous: Code executes non-blockingly, allowing other operations to run while waiting for the current one to complete. 
- JavaScript Pattern: JavaScript is single-threaded and uses an event-driven, non-blocking I/O model with callbacks, promises, and async/await for asynchronous operations. 
- Example: - console.log("Step 1"); setTimeout(() => console.log("Step 2"), 1000); // Non-blocking console.log("Step 3"); // Executes immediately 
- Use Case: - Web servers, APIs, database interactions, and any application involving I/O-bound tasks. 
 
 
4. What are the fundamental differences between TypeScript and JavaScript?
- TypeScript: A superset of JavaScript that adds static typing, interfaces, and advanced tooling for better code quality and maintainability. 
- JavaScript: Dynamically typed and more flexible but prone to runtime errors. 
5. What are higher-order functions?
- Definition: Functions that take other functions as arguments or return functions as results. 
- Example: - map(),- filter(), and- reduce().
6. What is the temporal dead zone in JavaScript?
- Definition: The period between the creation of a variable’s scope and its declaration, where accessing the variable results in a - ReferenceError.
7. How to handle multiple asynchronous operations in parallel using promises?
- Use - Promise.all():- const [result1, result2] = await Promise.all([promise1, promise2]); 
8. Difference between == and ===?
- ==: Compares values after type coercion.
- ===: Compares values and types without coercion.
9. Why is it important to use async/await for asynchronous code?
- Readability: Makes asynchronous code look synchronous and easier to understand. 
- Error Handling: Simplifies error handling with - try/catch.
10. Why is JavaScript called a single-threaded language?
- 1. Core Design Principle- JavaScript was designed to run in the browser environment, where it needed to handle user interactions, DOM manipulations, and network requests efficiently. 
- To keep the language simple and avoid complexities like race conditions and deadlocks, JavaScript was implemented as a single-threaded language. 
 - 2. Single Thread of Execution- JavaScript has only one call stack, meaning it can execute only one task at a time. 
- This single thread is responsible for executing all JavaScript code, including functions, event handlers, and callbacks. 
 - 3. Event-Driven, Non-Blocking Model- Despite being single-threaded, JavaScript can handle asynchronous operations efficiently using the event loop. 
- The event loop allows JavaScript to offload long-running tasks (e.g., I/O operations, timers) to the browser or Node.js runtime and continue executing other tasks without blocking the main thread. 
 - 4. Concurrency Through the Event Loop- The event loop continuously checks the call stack and processes tasks from the callback queue or microtask queue. 
- This mechanism enables JavaScript to handle multiple tasks concurrently without requiring multiple threads. 
 - Implications of Single-Threaded Nature- 1. Advantages- Simplicity: Easier to write and reason about code without worrying about thread synchronization or race conditions. 
- Predictability: Single-threaded execution ensures a predictable flow of operations. 
- Efficient for I/O-Bound Tasks: The event-driven model makes JavaScript highly efficient for handling I/O-bound tasks like network requests, file operations, and user interactions. 
 - 2. Challenges- CPU-Intensive Tasks: Since JavaScript runs on a single thread, CPU-intensive tasks (e.g., complex calculations, image processing) can block the main thread, making the application unresponsive. 
- Scalability: For CPU-bound workloads, additional techniques like worker threads (in Node.js) or Web Workers (in browsers) are required to achieve parallelism. 
 - How JavaScript Handles Concurrency
- Event Loop: - The core of JavaScript's concurrency model. 
- Continuously checks the call stack and processes tasks from the callback queue. 
- Enables non-blocking behavior by deferring long-running tasks and executing them once the call stack is empty. 
 
- Callbacks: - Functions passed as arguments to asynchronous operations, executed once the operation completes. 
- Example: - fs.readFile("file.txt", (err, data) => { if (err) throw err; console.log(data); }); 
 
- Promises: - Represent the eventual completion (or failure) of an asynchronous operation. 
- Provide a cleaner way to handle asynchronous code compared to callbacks. 
- Use - .then()for success,- .catch()for errors, and- .finally()for cleanup. Alternatively, use- async/awaitfor cleaner syntax.
- Example: - fetch("https://api.example.com/data") .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error(error)); 
 
- Async/Await: - Syntactic sugar built on top of promises. 
- Makes asynchronous code look synchronous, improving readability. 
- Example: - 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); } } 
 
Example
console.log("Start");
setTimeout(() => {
  console.log("Timeout Callback");
}, 1000);
Promise.resolve().then(() => {
  console.log("Promise Callback");
});
console.log("End");
console.log("Start"); setTimeout(() => { console.log("Timeout Callback"); }, 1000); Promise.resolve().then(() => { console.log("Promise Callback"); }); console.log("End");
Output:
Start End Promise Callback Timeout Callback
- Explanation: - Synchronous code ( - console.log("Start")and- console.log("End")) executes first.
- The - Promisecallback is a microtask and executes before the- setTimeoutcallback, which is a macrotask.
 
11. Primitive data types and type coercion in JavaScript.
- Primitive Types: - string,- number,- boolean,- null,- undefined,- symbol,- bigint.
- Type Coercion: Automatic conversion of values from one type to another (e.g., - "5" + 2results in- "52").
12. Difference between for..in and for..of loops.
- for..in: Iterates over enumerable properties of an object (keys).
- for..of: Iterates over iterable objects like arrays, strings, etc. (values).
13. Concept of function hoisting and closures.
- Hoisting: Functions and variables are moved to the top of their scope during compilation. 
- Closures: Functions that retain access to their lexical scope even after the outer function has executed. 
14. How to extend a class using ES6 syntax and call the super constructor.
- Example: - class Parent { constructor(name) { this.name = name; } } class Child extends Parent { constructor(name, age) { super(name); // Call super constructor this.age = age; } } 
15. Importance of this keyword in constructors.
- this: Refers to the instance of the class being created. Used to assign properties to the object.
16. Difference between null and undefined.
- null: Represents an intentional absence of value.
- undefined: Represents an uninitialized or missing value.
17. Why use async/await for asynchronous code?
- Readability: Makes asynchronous code look synchronous. 
- Error Handling: Simplifies error handling with - try/catch.
18. Valid variable names in JavaScript.
- Rules: - Must start with a letter, - _, or- $.
- Cannot start with a number. 
- Cannot use reserved keywords. 
 
19. Array methods like splice(), push(), and map().
- splice(): Adds/removes elements from an array.
- push(): Adds elements to the end of an array.
- map(): Creates a new array by applying a function to each element.
20. What are closures?
- Definition: A function that retains access to its lexical scope, even when executed outside that scope. 
- Example: - function outer() { let count = 0; return function inner() { count++; return count; }; } const counter = outer(); console.log(counter()); // 1 
21. Arrow functions in JavaScript.
- Syntax: - const add = (a, b) => a + b;
- Features: No - thisbinding, concise syntax.
22. Can functions be assigned to values in JavaScript?
- Yes: Functions are first-class citizens and can be assigned to variables. 
- Example: - const greet = function() { console.log('Hello!'); }; 
 
No comments:
Post a Comment