1. Difference between var, let, and const keywords in JavaScript.
1.
varScope: 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 withundefined.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.
letScope: 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 aReferenceError(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.
constScope: Block-scoped, similar to
let.Hoisting: Variables declared with
constare hoisted but not initialized. Accessing them before declaration results in aReferenceError.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 varletconstScope 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: Useconstby default for variables that do not need reassignment. This promotes immutability and reduces side effects.Use
letfor Mutability: Useletonly when reassignment is necessary, such as in loops or dynamic value updates.Block Scoping: Leverage block scoping (
letandconst) 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(), andreduce().
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, useasync/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")andconsole.log("End")) executes first.The
Promisecallback is a microtask and executes before thesetTimeoutcallback, 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