└── README.md /README.md: -------------------------------------------------------------------------------- 1 | # 100 Common JavaScript Interview Questions in 2025 2 | 3 |
4 |

5 | 6 | web-and-mobile-development 7 | 8 |

9 | 10 | #### You can also find all 100 answers here 👉 [Devinterview.io - JavaScript](https://devinterview.io/questions/web-and-mobile-development/javascript-interview-questions) 11 | 12 |
13 | 14 | ## 1. What are the _data types_ present in JavaScript? 15 | 16 | JavaScript has **primitive** and **composite** data types. 17 | 18 | ### Primitive Data Types 19 | 20 | - **Boolean**: Represents logical values of **true** or **false**. 21 | - **Null**: Denotes the lack of a value. 22 | 23 | - **Undefined**: Indicates a variable that has been declared but has not been assigned a value. 24 | 25 | - **Number**: Represents numeric values, including integers and floats. 26 | 27 | - **BigInt**: Allows for representation of integers with arbitrary precision. 28 | 29 | - **String**: Encapsulates sequences of characters. 30 | 31 | - **Symbol** (ES6): Provides a unique, immutable value. 32 | 33 | ### Composite Data Types 34 | 35 | - **Object**: Represents a set of key-value pairs and is used for more complex data structures. 36 | - **Function**: A callable object that can be defined using regular function syntax or using the `new Function()` constructor (rarely used). 37 | 38 | ### Notable Characteristics 39 | 40 | - JavaScript is **dynamically-typed**, meaning the data type of a variable can change during the execution of a program. 41 | - **Data type coercion** can occur, where values are implicitly converted from one type to another in specific contexts, such as during comparisons. 42 | - Arithmetic operations, particularly when one of the operands is a string, can lead to **implicit type conversions**. 43 |
44 | 45 | ## 2. What is the difference between _null_ and _undefined_? 46 | 47 | While both **null** and **undefined** represent "no value" in JavaScript, they are distinct in their roles and origins. 48 | 49 | ### Origin and Context 50 | 51 | - **null** usually denotes an intentionally **absent** value, and developers can set a variable to null to signify the absence of an object or a value. For example, if an API call doesn't return data, you might set a variable to null. 52 | 53 | - **undefined** typically indicates a variable that has been declared but not yet been assigned a value, or a property that doesn't exist on an object. 54 | 55 | ### Variable Initialization and Assignment 56 | 57 | - Variables that haven't been assigned a value are `undefined` by default, unless explicitly set to `null`. 58 | ```javascript 59 | let foo; // undefined 60 | let bar = null; // null 61 | ``` 62 | 63 | ### Function Arguments 64 | 65 | - When a function is called, and the parameter isn't provided or its value is not set, the parameter is `undefined`. 66 | - **null** would instead be an explicit value provided as an argument. 67 | 68 | ### Object Properties 69 | 70 | - If you try to access a property on an object that doesn't exist, the result is `undefined`. 71 | ```javascript 72 | let obj = {}; 73 | console.log(obj.nonExistentProperty); // undefined 74 | ``` 75 | 76 | - **Null** can be used to clear a property value in an object that was previously set. 77 | ```javascript 78 | let obj = { prop: 'value' }; 79 | obj.prop = null; 80 | ``` 81 | 82 | ### The Equality Operation 83 | 84 | - In JavaScript, **undefined** and **null** are treated as equal when using loose equality (==) but not strict equality (===). 85 | 86 | ### Use-Cases and Best Practices 87 | 88 | - When you initialize a variable and are not ready to assign a meaningful value, it's more common to use **undefined** instead of **null** to indicate that the value isn't there yet. 89 | - For example, if you declare a user object but don't have their details yet, you might keep it as `undefined`. 90 | 91 | ### Code Example 92 | 93 | Here is the JavaScript code: 94 | 95 | ```javascript 96 | let var1; 97 | let var2 = null; 98 | 99 | let object = { 100 | a: 1, 101 | b: undefined 102 | }; 103 | 104 | function test(arg1, arg2) { 105 | console.log(arg1); // undefined: not provided 106 | console.log(arg2); // null: provided as such 107 | } 108 | 109 | function clearProperty(prop) { 110 | delete object[prop]; 111 | } 112 | 113 | console.log(var1); // undefined 114 | console.log(var2); // null 115 | console.log(object.a); // 1 116 | console.log(object.b); // undefined 117 | console.log(object.c); // undefined 118 | 119 | test(); // Both arguments are undefined 120 | test(1, null); // arg1 is 1, arg2 is null 121 | 122 | clearProperty('b'); // Removes property 'b' from object 123 | console.log(object.b); // undefined: Property 'b' was removed, not set to null 124 | ``` 125 |
126 | 127 | ## 3. How does JavaScript handle _type coercion_? 128 | 129 | **Type Coercion** in JavaScript refers to the automatic conversion of values from one data type to another. 130 | 131 | ### Explicit and Implicit Coercion 132 | 133 | - **Explicit**: Achieved through methods such as `parseInt()`, `Number()`, and `toString()`. 134 | - **Implicit**: Automatically occurs during operations or comparisons. For example, combining a string and a number in an addition results in the automatic conversion of the number to a string. 135 | 136 | ### Common Coercion Scenarios 137 | 138 | 1. **Arithmetic Operations**: Strings are coerced to numbers. 139 | - **Example**: `"5" - 3` evaluates to `2`, as the string is coerced to a number. 140 | 141 | 2. **Loose Equality (==)**: Data types are often modified for comparisons. 142 | - **Example**: `"4" == 4` is `true` due to string coercion before the comparison. 143 | 144 | 3. **Conditionals** (if and Ternary Operators): Truthiness or falsiness is determined. 145 | - **Example**: `if(1)` evaluates to `true` because `1` coerces to `true`. 146 | 147 | 4. **Logical Operators**: Non-boolean values are coerced to booleans. 148 | - **Example**: `"hello" && 0` evaluates to `0` because the truthy `"hello"` short-circuits the `&&` operation, and `0` coerces to `false`. 149 |
150 | 151 | ## 4. Explain the concept of _hoisting_ in JavaScript. 152 | 153 | **Hoisting** is a JavaScript mechanism that involves moving variable and function declarations to the top of their containing scope **during the compile phase**. However, the assignments to these variables or the definitions of functions remain in place. 154 | 155 | For instance, even though the call to `myFunction` appears before its definition, hoisting ensures that it doesn't cause an error. 156 | 157 | ### Hoisting in Action 158 | 159 | Here's a Code Example: 160 | 161 | ```javascript 162 | console.log(myVar); // Undefined 163 | var myVar = 5; 164 | 165 | console.log(myVar); // 5 166 | 167 | // The above code is equivalent to the following during the compile phase: 168 | // var myVar; 169 | // console.log(myVar); 170 | // myVar = 5; 171 | 172 | console.log(sayHello()); // "Hello, World!" 173 | function sayHello() { 174 | return "Hello, World!"; 175 | } 176 | 177 | // The above code is equivalent to the following during the compile phase: 178 | // function sayHello() { 179 | // return "Hello, World!"; 180 | // } 181 | // console.log(sayHello()); 182 | ``` 183 | 184 | ### Why Hoisting Matters 185 | 186 | Understanding hoisting can help you prevent certain unexpected behaviors in your code. For example, it can shed light on unexpected "undefined" values that might appear even after a variable is declared and initialized. 187 | 188 | #### Global Scope and Hoisting 189 | 190 | In the global scope, variables declared with `var` and functions are always hoisted to the top. For example: 191 | 192 | ```javascript 193 | // During the compile phase, the following global declarations are hoisted: 194 | // var globalVar; 195 | // function globalFunction() {} 196 | 197 | console.log(globalVar); // Undefined 198 | console.log(globalFunction()); // "Hello, Global!" 199 | var globalVar = "I am global Var!"; 200 | function globalFunction() { 201 | return "Hello, Global!"; 202 | } 203 | ``` 204 | 205 | #### Local Scope and Hoisting 206 | 207 | Variables and functions declared in local scopes within functions are also hoisted to the top of their scope. 208 | 209 | Here's a Code Example: 210 | 211 | ```javascript 212 | function hoistingInLocalScope() { 213 | // These local declarations are hoisted during the compile phase: 214 | // var localVar; 215 | // function localFunction() {} 216 | 217 | console.log(localVar); // Undefined 218 | localVar = "I am a local var!"; 219 | console.log(localFunction()); // "Hello, Local!" 220 | 221 | var localVar; 222 | function localFunction() { 223 | return "Hello, Local!"; 224 | } 225 | } 226 | ``` 227 | 228 | ### Best Practices 229 | 230 | To write clean, readable code, it's important to: 231 | 232 | - Declare variables at the top of your scripts or functions to avoid hoisting-related pitfalls. 233 | - Initialize variables before use, **regardless of hoisting**, to ensure predictable behavior. 234 | 235 | ### ES6 and Hoisting 236 | 237 | With the introduction of `let` and `const` in ES6, JavaScript's behavior has adapted. Variables declared using `let` and `const` are still hoisted, but unlike `var`, they are **not initialized**. 238 | 239 | Here's an Example: 240 | 241 | ```javascript 242 | console.log(myLetVar); // ReferenceError: Cannot access 'myLetVar' before initialization 243 | let myLetVar = 5; 244 | ``` 245 | 246 | ### Constants and Hoisting 247 | 248 | `const` and `let` behave similarly when hoisted, but their difference lies in the fact that `const` must be assigned a value at the time of declaration, whereas `let` does not require an initial value. 249 | 250 | Here's an Example: 251 | 252 | ```javascript 253 | console.log(myConstVar); // ReferenceError: Cannot access 'myConstVar' before initialization 254 | const myConstVar = 10; 255 | 256 | console.log(myLetVar); // Undefined 257 | let myLetVar = 5; 258 | ``` 259 |
260 | 261 | ## 5. What is the _scope_ in JavaScript? 262 | 263 | **Scope** defines the accessibility and lifetime of variables in a program. In JavaScript, there are two primary types: **Global Scope** and **Local Scope**. 264 | 265 | ### Global Scope 266 | 267 | Any variable declared **outside of a function** is in the global scope. These can be accessed from both within functions and from other script tags. 268 | 269 | #### Example: Global Scope 270 | 271 | Here is the JavaScript code: 272 | 273 | ```javascript 274 | let globalVar = 'I am global'; 275 | 276 | function testScope() { 277 | console.log(globalVar); // Output: 'I am global' 278 | } 279 | 280 | testScope(); 281 | console.log(globalVar); // Output: 'I am global' 282 | ``` 283 | 284 | ### Local Scope 285 | 286 | Variables declared within a **function** (using `let` or `const` or prior to JavaScript ES6 with `var`) have local scope, meaning they are only accessible within that function. 287 | 288 | #### Example: Local Scope 289 | 290 | Here is the JavaScript code: 291 | 292 | ```javascript 293 | function testScope() { 294 | let localVar = 'I am local'; 295 | console.log(localVar); // Output: 'I am local' 296 | } 297 | 298 | // This statement will throw an error because localVar is not defined outside the function scope 299 | // console.log(localVar); 300 | ``` 301 | 302 | ### Block Scope 303 | 304 | Starting from **ES6**, JavaScript also supports block scope, where variables defined inside code blocks (denoted by `{}` such as loops or conditional statements) using `let` or `const` are accessible only within that block. 305 | 306 | #### Example: Block Scope 307 | 308 | Here is the JavaScript code: 309 | 310 | ```javascript 311 | function testScope() { 312 | let localVar = 'I am local'; 313 | if (true) { 314 | let blockVar = 'I am local to this block'; 315 | console.log(localVar, blockVar); // Both will be accessible 316 | } 317 | // This statement will throw an error because blockVar is not defined outside the block scope 318 | // console.log(blockVar); 319 | } 320 | 321 | testScope(); 322 | ``` 323 |
324 | 325 | ## 6. What is the difference between `==` and `===`? 326 | 327 | **Strict equality** (`===`) in JavaScript requires both value and type to match, testing for more specific conditions and reducing the likelihood of unexpected results. 328 | 329 | In contrast, the **abstract equality** comparison (`==`) can lead to type coercion, potentially causing counterintuitive outcomes. 330 | 331 | While both comparison modes test value equality, `===` ensures an additional match of data type. 332 | 333 | ### Illustrative Example: Abstract vs. Strict Equality 334 | 335 | - Abstract Equality: 336 | - `5 == '5'` evaluates to `true` because JavaScript converts the string to a number for comparison. 337 | - Strict Equality: 338 | - `5 === '5'` evaluates to `false` because the types are not the same. 339 | 340 | ### Key Considerations 341 | 342 | - **Type Safety**: `===` is safer as it avoids unwanted type conversions. 343 | - **Performance**: `===` can be faster, especially for simple comparisons, as it doesn't involve type coercion or additional checks. 344 | - **Clarity**: Favoring `===` can make your code clearer and more predictable. 345 | 346 | ### Common Best Practices 347 | 348 | - **Use Strict Equality by Default**: This approach minimizes unintended side effects. 349 | - **Consider Type Coercion Carefully**: In specific cases or with proven understanding, `==` can be suitable, but be cautious about potential confusion. 350 | 351 | ### Code Example: Equality Operators 352 | 353 | Here is the JavaScript code: 354 | 355 | ```javascript 356 | // Abstract equality 357 | console.log('5' == 5); // true 358 | console.log(null == undefined); // true 359 | console.log(0 == false); // true 360 | 361 | // Strict equality 362 | console.log('5' === 5); // false 363 | console.log(null === undefined); // false 364 | console.log(0 === false); // false 365 | ``` 366 |
367 | 368 | ## 7. Describe _closure_ in JavaScript. Can you give an example? 369 | 370 | In JavaScript, **closures** enable a **function** to access its outer scope, retaining this access even after the parent function has finished executing. This mechanism provides a powerful tool for data encapsulation and privacy. 371 | 372 | ### Core Concept 373 | 374 | When a **function** is defined within another function, it maintains a reference to the variables from the outer function, even after the outer function has completed execution and its local variables are typically no longer accessible. 375 | 376 | ### Key Components 377 | 378 | 1. **Outer Function (Parent function)**: It contains the inner functions or closures. 379 | 2. **Inner Function (Closure)**: Defined within the parent function, it references variables from the outer function. 380 | 3. **Lexical Environment**: The context where the inner function is defined, encapsulating the scope it has access to. 381 | 382 | ### Example: Password Generator 383 | 384 | Consider a simple scenario of a function in charge of generating a secret password: 385 | 386 | 1. The outer function, `generatePassword`, defines a local variable, `password` and returns an inner function `getPassword`. 387 | 2. The inner function, `getPassword`, has exclusive access to the `password` variable even after `generatePassword` has executed. 388 | 389 | Here is the JavaScript code: 390 | 391 | ```javascript 392 | function generatePassword() { 393 | let password = ''; 394 | const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; 395 | const passwordLength = 8; 396 | for(let i = 0; i < passwordLength; i++) { 397 | password += characters.charAt(Math.floor(Math.random() * characters.length)); 398 | } 399 | 400 | return function getPassword() { 401 | return password; 402 | }; 403 | } 404 | 405 | const getPassword = generatePassword(); 406 | 407 | console.log(getPassword()); // Outputs the generated password. 408 | ``` 409 | 410 | In this example, `getPassword` still has access to the `password` variable after the `generatePassword` function has completed, thanks to the closure mechanism. 411 | 412 | ### Application 413 | 414 | - **Data Privacy**: JavaScript design patterns like the Module and Revealing Module Patterns use closures to keep data private. 415 | 416 | - **Timeouts and Event Handlers**: Closures help preserve the surrounding context in asynchronous operations such as `setTimeout` and event handlers. 417 | 418 | ### Pitfalls to Avoid 419 | 420 | - **Memory Leakage**: If not used carefully, closures can cause memory leaks, as the outer function's variables continue to live in memory because of the closure link. 421 | - **Stale Data**: Be mindful of shared variables that might change after a closure has been defined, leading to unexpected behavior. 422 | 423 | ### Browser Compatibility 424 | 425 | The concept of closures is a fundamental aspect of the JavaScript language and is supported by all modern browsers and environments. 426 |
427 | 428 | ## 8. What is the '_this_ keyword' and how does its context change? 429 | 430 | In JavaScript, the context of **`this`** refers to the execution context, typically an object that owns the function where `this` is used. 431 | 432 | ### 'this' in the Global Scope 433 | 434 | In **non-strict** mode, `this` in the global scope refers to the `window` object. In **strict** mode, `this` is `undefined`. 435 | 436 | ### 'this' in Functions 437 | 438 | In **non-arrow functions**, the value of `this` depends on how the function is **invoked**. When invoked: 439 | 440 | - As a method of an object: `this` is the object. 441 | - Alone: In a browser, `this` is `window` or `global` in Node.js. In strict mode, it's `undefined`. 442 | - With `call`, `apply`, or `bind`: `this` is explicitly set. 443 | - As a constructor (with `new`): `this` is the newly created object. 444 | 445 | ### 'this' in Arrow Functions 446 | 447 | Arrow functions have a **fixed context** for `this` defined at **function creation** and are not changed by how they are invoked. 448 | 449 | - They do **not have** their own `this`. 450 | - They use the `this` from their surrounding lexical context (the enclosing function or global context). 451 | 452 | ### Code Example: Global Context 453 | 454 | Here is the JavaScript code: 455 | 456 | ```javascript 457 | // Main 458 | let globalVar = 10; 459 | 460 | function globalFunction() { 461 | console.log('Global this: ', this.globalVar); 462 | console.log('Global this in strict mode: ', this); 463 | } 464 | 465 | globalFunction(); // Output: 10, window or undefined (in strict mode) 466 | 467 | // In Node.js, it will be different, because "window" is not defined. But "this" will refer to the global object. 468 | ``` 469 |
470 | 471 | ## 9. What are _arrow functions_ and how do they differ from regular functions? 472 | 473 | Let's look at the key features of **arrow functions** and how they differ from traditional functions in JavaScript. 474 | 475 | ### Arrow Functions: Key Features 476 | 477 | - **Concise Syntax**: 478 | - Especially useful for short, one-liner functions. 479 | - No need for `function` keyword or **braces** if there's a single expression. 480 | 481 | - **Implicit Return**: 482 | - When there's no explicit `{ return ... ;}` statement, arrow functions return the result of the single expression inside. 483 | 484 | - **`this` Binding**: 485 | - Does not have its **own `this`**. It's "inherited" from the surrounding (lexical) context. This feature is known as '**lexical scoping**'. 486 | 487 | ### Code Example: Standard Function vs. Arrow Function 488 | 489 | Here is the JavaScript code: 490 | 491 | ```javascript 492 | // Standard Function 493 | function greet(name) { 494 | return "Hello, " + name + "!"; 495 | } 496 | 497 | // Arrow Function 498 | const greetArrow = name => "Hello, " + name + "!"; 499 | ``` 500 | 501 | In the code above, `greet` is a standard function, while `greetArrow` is an arrow function, showcasing the difference in syntax and required keywords. 502 | 503 | ### When to Use Arrow Functions 504 | 505 | - **Event Handlers**: Ideal for concise, inline event handling, where `this` context can be inherited from the lexical scope. 506 | 507 | - **Callback Functions**: Useful for array methods like `map`, `filter`, and `reduce`. 508 | 509 | - **Avoidance of `this` Redefinition**: When you want to maintain the surrounding context of `this` and avoid unintended redefinition. 510 | 511 | ### Code Example: Arrow Function and `this` Context 512 | 513 | Here is the JavaScript code: 514 | 515 | ```javascript 516 | // Using traditional functions 517 | document.getElementById('myButton').onclick = function() { 518 | console.log('Button clicked:', this); // Refers to the button element 519 | }; 520 | 521 | // Using arrow functions 522 | document.getElementById('myButton').onclick = () => { 523 | console.log('Button clicked:', this); // Refers to the global/window object 524 | }; 525 | ``` 526 | 527 | In the arrow function example, the context of `this` does not refer to the button element, but to the global `window` object, because arrow functions do not have their own binding of `this`. Instead, they inherit `this` from their lexical scope, which in this case is the global context. 528 |
529 | 530 | ## 10. What are _template literals_ in JavaScript? 531 | 532 | **Template literals** are a feature in modern JavaScript versions that offer a more flexible and readable way to work with strings. They are often referred to as "template strings". 533 | 534 | ### Key Features 535 | 536 | - **Multiline Text**: Template literals support multiline strings without requiring escape characters or string concatenation with a `+` sign. 537 | - **String Interpolation**: They enable the seamless embedding of JavaScript expressions within strings, using `${}`. 538 | 539 | ### Syntax 540 | 541 | - **Single Versus Double Quotes**: For template literals, use backticks (\`) instead of single quotes ('') or double quotes (""). 542 | - **Placeholder**: The `${expression}` placeholder within the backticks allows for variable and expression injection. 543 | 544 | ### Example: 545 | 546 | ```javascript 547 | let name = "John"; 548 | let message = `Hi ${name}!`; 549 | 550 | console.log(message); // Output: "Hi John!" 551 | ``` 552 | 553 | ### Benefits 554 | 555 | - **Readability**: They can make code more understandable, especially when dealing with longer or complex strings, by keeping content closer to its intention. 556 | - **Interpolation & Expression**: Template literals reduce verbosity and rendering logic when integrating dynamic data. 557 | 558 | ### Code Example: Multiline Text and String Interpolation 559 | 560 | ```javascript 561 | // Regular String 562 | let poem = "Roses are red,\nViolets are blue,\nSugar is sweet,\nAnd so are you."; 563 | 564 | // Template Literal 565 | let poemTemplate = ` 566 | Roses are red, 567 | Violets are blue, 568 | Sugar is sweet, 569 | And so are you. 570 | `; 571 | ``` 572 | 573 | ### Browser Compatibility Concerns 574 | 575 | Template literals are universally supported in modern browsers and are now considered a **core JavaScript feature**. However, they may not work in older browsers such as Internet Explorer without transpilation or polyfilling. 576 |
577 | 578 | ## 11. What is a _higher-order function_ in JavaScript? 579 | 580 | A **higher-order function** in JavaScript is a function that can take other functions as arguments or can return functions. This feature enables functional programming paradigms such as `map`, `reduce`, and `filter`. Higher-order functions offer versatility and modularity, fostering streamlined, efficient code. 581 | 582 | ### Key Characteristics 583 | 584 | - **First-class functions**: Functions in JavaScript are considered first-class, meaning they are a legitimate data type and can be treated like any other value, including being assigned to variables, stored in data structures, or returned from other functions. 585 | 586 | - **Closure support**: Due to closures, a higher-order function can transport not just the enclosed data within the function definition, but also the lexical environment in which that data resides. 587 | 588 | - **Dynamic code**: Because JavaScript allows functions to be dynamically constructed and named, they can be dynamically passed to higher-order functions. 589 | 590 | ### Practical Applications 591 | 592 | - **Callback Execution**: Functions like `setTimeout` and `addEventListener` take a function as an argument and are thus higher-order. 593 | 594 | - **Event Handling**: Many event-driven systems leverage higher-order functions for tasks such as event subscription and emission. 595 | 596 | - **Iterative Operations**: The `map`, `filter`, and `reduce` functions in JavaScript operate on arrays and require functions to be passed, making them higher-order. 597 | 598 | - **Code Abstraction**: Higher-order functions enable the encapsulation of repetitive tasks, promoting cleaner, more readable code. 599 | 600 | ### Code Example: Higher-order Functions 601 | 602 | Here is the JavaScript code: 603 | 604 | ```javascript 605 | // Simple higher-order function 606 | function multiplier(factor) { 607 | return function(num) { 608 | return num * factor; 609 | }; 610 | } 611 | 612 | // Invoke a higher-order function 613 | const twice = multiplier(2); 614 | console.log(twice(5)); // Output: 10 615 | 616 | // Functional programming with higher-order functions 617 | const numbers = [1, 2, 3, 4, 5]; 618 | const doubled = numbers.map(multiplier(2)); // [2, 4, 6, 8, 10] 619 | const tripled = numbers.map(multiplier(3)); // [3, 6, 9, 12, 15] 620 | ``` 621 |
622 | 623 | ## 12. Can functions be assigned as values to variables in JavaScript? 624 | 625 | Yes, **JavaScript** supports first-class functions, meaning **functions can be treated as variables** and then assigned to other variables or passed as arguments to other functions. 626 | 627 | Functions defined as regular functions or arrow functions are both first-class in JavaScript. 628 | 629 | ### Practical Code Example 630 | 631 | Here is the JavaScript code: 632 | 633 | ```javascript 634 | // Define a function 635 | function greet() { 636 | console.log('Hello!'); 637 | } 638 | 639 | // Assign the function to a variable 640 | let sayHello = greet; 641 | 642 | // Call the function through the variable 643 | sayHello(); // Output: "Hello!" 644 | 645 | // Reassign the variable to a new function 646 | sayHello = function() { 647 | console.log('Bonjour!'); 648 | }; 649 | 650 | // Call it again to see the new behavior 651 | sayHello(); // Output: "Bonjour!" 652 | ``` 653 | 654 | ### Practical Use Cases 655 | 656 | - **Callbacks**: Functions can be passed as parameters to other functions. 657 | 658 | - **Event Handling**: In web development, functions define how to respond to specific events, and these functions are often attached to event listeners. 659 | 660 | - **Modular Development**: In programming patterns like the Module pattern, functions are defined within a scope and then returned, similar to variables. 661 | 662 | - **Higher-Order Functions**: These functions operate on other functions, taking them as arguments or returning them, and are an essential part of many modern JavaScript libraries and frameworks. 663 |
664 | 665 | ## 13. How do _functional programming_ concepts apply in JavaScript? 666 | 667 | **Functional Programming** (FP) concepts in JavaScript are a direct result of the language's first-class functions. Key FP principles, such as immutability, pure functions, and **declarative** style, play a crucial role. 668 | 669 | ### Core Concepts 670 | 671 | #### First-Class Functions and Higher-Order Functions 672 | 673 | JavaScript treats functions as first-class citizens, allowing them to be assigned to variables, passed as parameters, and returned from other functions. This feature is foundational to FP in the language. 674 | 675 | #### Code Example: 676 | 677 | Here is the JavaScript code: 678 | 679 | ```javascript 680 | const sayHello = () => console.log('Hello!'); 681 | const runFunction = (func) => func(); 682 | 683 | runFunction(sayHello); // Output: "Hello!" 684 | ``` 685 |
686 | 687 | ## 14. What are _IIFEs_ (Immediately Invoked Function Expressions)? 688 | 689 | The **Immediately Invoked Function Expression** (IIFE) design pattern employs an anonymous function that gets executed promptly after its definition. 690 | 691 | Key characteristics of IIFEs include localized variable scopes and immediate activation upon interpreter parsing. 692 | 693 | ### Code Example: IIFE 694 | 695 | Here is the JavaScript code: 696 | 697 | ```javascript 698 | (function(){ 699 | var foo = 'bar'; 700 | console.log(foo); 701 | })(); 702 | ``` 703 | 704 | In this example, the function is enclosed within parentheses, ensuring the enclosed function is evaluated as an expression. Subsequently, it is invoked with a trailing pair of parentheses. 705 | 706 | ### Core Functions of IIFE 707 | 708 | 1. **Encapsulation**: Through lexical scoping, IIFEs safeguard variables from leaking into the global scope. This, in turn, averts unintended variable tampering in the global context. 709 | 710 | 2. **Data Hiding**: Internal functions or data can be hidden from external access, providing a mechanism for information concealment and access control. 711 | 712 | 3. **Initialization**: The IIFE structure is ideal for setting up initial conditions, like binding events or pre-processing data. 713 | 714 | ### Use Cases 715 | 716 | - **Avoiding Variable Pollution**: When interfacing with libraries or inserting code snippets, IIFEs prevent global scope pollution. 717 | 718 | - **Module Patterns**: IIFEs, in combination with **closures**, lay the groundwork for modular code organization by shielding private variables and functions. 719 | 720 | ### Modern Alternatives 721 | 722 | With the introduction of ES6 and its `let` and `const` declarations, as well as block-scoped lexical environments, the necessity of IIFEs has reduced. Additionally, **arrow functions** provide a more concise method for defining immediately invoked functions. 723 | 724 | ### IIFE Variants 725 | 726 | 1. **Parentheses Invocation**: A pair of parentheses immediately invoke the enclosed function. While this approach is more extensive, it's devoid of self-documenting advantages. 727 | ```javascript 728 | (function(){ 729 | console.log('Invoked!'); 730 | })(); 731 | ``` 732 | 733 | 2. **Wrapping in Operators**: Similar to using parentheses for invocation, the `!`, `+`, or `-` operators are sometimes used for invoking clarity. For instance: 734 | ```javascript 735 | !function(){ 736 | console.log('Invoked!'); 737 | }(); 738 | ``` 739 | 740 | 3. **Named IIFE**: Though not as common, naming an IIFE can assist with self-referencing. This is most effective when the intention is to have a more comprehensive stack trace during debugging. 741 | ```javascript 742 | (function factorial(n){ 743 | if (n <= 1) return 1; 744 | return n * factorial(n-1); 745 | })(5); 746 | ``` 747 | 748 | #### Caution on Minification 749 | 750 | When leveraging IIFEs, exercise caution while using minifiers to shrink JavaScript files. Minification might lead to unintended outcomes, altering the previous scope expectations. 751 |
752 | 753 | ## 15. How do you create _private variables_ in JavaScript? 754 | 755 | In JavaScript, encapsulating private state within an object can be achieved using a **closure**. This ensures the state is local to the object and not directly accessible from outside. 756 | 757 | ### How Closures Work 758 | 759 | A **closure** allows a function to retain access to the **lexical environment** (the set of variable bindings at the point of function declaration) in which it was defined, even when the function is executed outside that lexical environment. 760 | 761 | This means that any **inner function**, defined inside another function, has access to the **outer function's variables**, and that access is maintained even after the outer function has finished executing. 762 | 763 | For example: 764 | ```javascript 765 | function outerFunction() { 766 | let outerVar = 'I am outer'; // This variable is in the lexical environment of outerFunction 767 | 768 | function innerFunction() { 769 | console.log(outerVar); // Accesses outerVar from the lexical environment of outerFunction 770 | } 771 | 772 | return innerFunction; 773 | } 774 | 775 | let myInnerFunction = outerFunction(); 776 | myInnerFunction(); // Logs: "I am outer" 777 | ``` 778 | 779 | Here, `innerFunction` retains access to `outerVar`. 780 | 781 | ### Practical Implementation with Constructor Functions and Modules 782 | 783 | #### Constructor Functions 784 | 785 | When defining a JavaScript **constructor function** with `function` and `new`, closure can be used to associate private state with each instance: 786 | 787 | ```javascript 788 | function Gadget() { 789 | let secret = 'top secret'; 790 | this.setSecret = function (value) { 791 | secret = value; 792 | }; 793 | this.getSecret = function () { 794 | return secret; 795 | }; 796 | } 797 | 798 | let phone = new Gadget(); 799 | phone.setSecret('new secret'); 800 | console.log(phone.getSecret()); // 'new secret' 801 | ``` 802 | 803 | In this example, `secret` is private to each `Gadget` instance, thanks to closure. 804 | 805 | #### Modules 806 | 807 | In modern JavaScript, **module patterns** combined with **immediately-invoked function expressions** (IIFE) are often used for encapsulation and data hiding. 808 | 809 | - The **revealing module pattern** enables selective exposure of private members. 810 | 811 | - The **IIFE pattern** immediately executes and returns the object to be assigned, effectively creating a module. 812 | 813 | Here is the code: 814 | 815 | ```javascript 816 | let myModule = (function () { 817 | let privateVariable = 'I am private'; 818 | 819 | function privateMethod() { 820 | console.log('I am a private method'); 821 | } 822 | 823 | return { 824 | publicMethod: function () { 825 | console.log('I am a public method'); 826 | }, 827 | getPrivateVariable: function () { 828 | return privateVariable; 829 | } 830 | }; 831 | })(); 832 | 833 | console.log(myModule.getPrivateVariable()); // 'I am private' 834 | myModule.privateMethod(); // Throws an error because privateMethod is not exposed 835 | ``` 836 | 837 | In this example, `privateVariable` and `privateMethod` are accessible only within the IIFE's lexical environment, thus making them private. 838 | 839 | JavaScript tools like TypeScript and Babel also offer modules such as `module.export`, providing additional options for encapsulation. 840 |
841 | 842 | 843 | 844 | #### Explore all 100 answers here 👉 [Devinterview.io - JavaScript](https://devinterview.io/questions/web-and-mobile-development/javascript-interview-questions) 845 | 846 |
847 | 848 | 849 | web-and-mobile-development 850 | 851 |

852 | 853 | --------------------------------------------------------------------------------