└── README.md /README.md: -------------------------------------------------------------------------------- 1 | # 🔥 JavaScript Brain Teasers & Debugging Interview Questions 2 | 3 | ## 🚀 About This Repository 4 | 5 | Welcome to the **JavaScript Brain Teasers & Debugging Interview Questions** repository! 🎯 This is your go-to resource for **real-world JavaScript debugging challenges** and **tricky interview questions**, inspired by actual problems faced by developers in top tech companies. 6 | 7 | If you've ever spent hours debugging **weird JavaScript behavior**, this repo is for you! You'll find **structured explanations**, **solutions**, and **best practices** to sharpen your debugging skills and **ace JavaScript interviews**. 8 | 9 | --- 10 | 11 | ## 📌 Table of Contents 12 | 13 | 1. [Tricky JavaScript Questions](#-tricky-javascript-questions) 14 | 15 | 2. [Contributing](#-contributing) 16 | --- 17 | 18 | ## 🧠 Tricky JavaScript Questions 19 |
20 | 21 | 1- JS types 22 | 23 | ```js 24 | console.log(typeof NaN); 25 | console.log(typeof undefined); 26 | console.log(typeof null); 27 | console.log(typeof 1); 28 | console.log(typeof typeof "1"); 29 | console.log(typeof typeof 1); 30 | console.log(typeof Number); 31 | ``` 32 |
33 | 34 | - 2- Temporal Dead Zone (TDZ) for let variables 35 | 36 | ```jsx 37 | let x = 1; 38 | function outer() { 39 | console.log(x); 40 | let x = 2; 41 | } 42 | outer(); 43 | // What's the output and why? 44 | ``` 45 | 46 | - 3- Block scope TDZ 47 | 48 | ```jsx 49 | let x = 1; 50 | { 51 | console.log(x); 52 | let x = 2; 53 | } 54 | ``` 55 | 56 | - 4- const with different types 57 | 58 | ```jsx 59 | 60 | const number = 42; 61 | const numbers = [1, 2, 3]; 62 | const obj = { 63 | count: 0 64 | }; 65 | 66 | // Test Cases: 67 | console.log(number++); // Case 1 68 | console.log(numbers.push(4)); // Case 2 69 | console.log(numbers = [5, 6]); // Case 3 70 | console.log(obj.count++); // Case 4 71 | console.log(obj = { count: 1 }); // Case 5 72 | ``` 73 | 74 | - 5- Hoisting 75 | 76 | ```jsx 77 | function sayHi() { 78 | console.log(name); 79 | console.log(age); 80 | var name = "John"; 81 | let age = 20; 82 | } 83 | sayHi(); 84 | ``` 85 | 86 | - 6- Function declaration hoisting 87 | 88 | ```jsx 89 | function getMessage() { 90 | function message() { 91 | return "Hello"; 92 | } 93 | return message(); 94 | function message() { 95 | return "Goodbye"; 96 | } 97 | } 98 | console.log(getMessage()); 99 | ``` 100 | 101 | - 7- Boolean & Number conversion of strings 102 | 103 | ```jsx 104 | console.log(Boolean("false")); 105 | console.log(Boolean(false)); 106 | console.log(Number("false")); 107 | console.log(Number(false)); 108 | console.log(Number("1")); 109 | console.log(Number(1)); 110 | ``` 111 | 112 | - 8- Type coercion with unary plus 113 | 114 | ```jsx 115 | console.log("b" + "a" + +"a" + "a"); 116 | ``` 117 | 118 | - 9- Unary plus type conversion 119 | 120 | ```jsx 121 | console.log(+""); 122 | console.log(+[]); 123 | console.log(+{}); 124 | ``` 125 | 126 | - 10- Basic array/object coercion 127 | 128 | ```jsx 129 | console.log([] + []); 130 | console.log(![] + []); 131 | console.log([] + {}); 132 | console.log({} + []); 133 | console.log({} + {}); 134 | ``` 135 | 136 | - 11- Complex coercion and array indexing 137 | 138 | ```jsx 139 | console.log((![] + [])[+[]] + (![] + [])[+!+[]] + ([![]] + [][[]])[+!+[] + [+[]]]) 140 | ``` 141 | 142 | - 12- Number Method Syntax & JavaScript Parser Behavior 143 | 144 | ```jsx 145 | console.log(5.toString()); 146 | console.log(5..toString()); 147 | console.log(1.0.toString()); 148 | console.log(-1 .toString()); 149 | console.log(parseInt(".5")); 150 | ``` 151 | 152 | - 13- Numeric Literal Syntax and Octal Numbers 153 | 154 | ```jsx 155 | const num1 = 02020; 156 | const num2 = 0o2020; 157 | console.log(num1); 158 | console.log(num2); 159 | ``` 160 | 161 | - 14- Floating-point precision in JavaScript 162 | 163 | ```jsx 164 | let result = 0.1 + 0.2; 165 | console.log(result === 0.3); 166 | console.log(((0.1 + 0.2 * 10) / 10) === 0.3); 167 | console.log((0.1 + 0.2 + 0.3).toFixed(1)); 168 | ``` 169 | 170 | - 15- Math.min/max with no arguments 171 | 172 | ```jsx 173 | console.log(Math.min() > Math.max()); 174 | console.log(Math.min() < Math.max()); 175 | console.log(Math.min() === -Infinity); 176 | ``` 177 | 178 | - 16- Number Type Conversion Methods & Parsing Behavior 179 | 180 | ```jsx 181 | console.log(parseInt("123abc")); 182 | console.log(Number("123abc")); 183 | 184 | console.log(parseInt("abc123")); 185 | console.log(Number("abc123")); 186 | 187 | console.log(parseInt("12.34")); 188 | console.log(Number("12.34")); 189 | 190 | console.log(parseInt("")); 191 | console.log(Number("")); 192 | ``` 193 | 194 | - 17- Type coercion in loose equality 195 | 196 | ```jsx 197 | console.log(null == undefined); 198 | console.log(null == false); 199 | console.log(undefined == false); 200 | console.log(null == 0); 201 | console.log(undefined == 0); 202 | console.log([] == ![]); 203 | ``` 204 | 205 | - 18- Type coercion with + operator 206 | 207 | ```jsx 208 | console.log(1 + "2" + "2"); 209 | console.log(1 + +"2" + "2"); 210 | console.log([1,2] + [3,4]); 211 | console.log(+true + ""); 212 | console.log(true + false); 213 | ``` 214 | 215 | - 19- Object and array addition 216 | 217 | ```jsx 218 | console.log([] + {}); 219 | console.log({} + []); 220 | console.log([] + []); 221 | console.log({} + {}); 222 | ``` 223 | 224 | - 20- Null comparisons 225 | 226 | ```jsx 227 | console.log(null > 0); 228 | console.log(null == 0); 229 | console.log(null >= 0); 230 | console.log(null > false); 231 | console.log(null == false); 232 | console.log(null >= false); 233 | ``` 234 | 235 | - 21- Array self-comparison 236 | 237 | ```jsx 238 | const arr = [1, 2, 3]; 239 | console.log(arr > arr); 240 | console.log(arr >= arr); 241 | console.log([] > []); 242 | ``` 243 | 244 | - 22- Array and negated array and Object comparison 245 | 246 | ```jsx 247 | console.log([] > ![]); 248 | console.log([] == ![]); 249 | console.log([] === ![]); 250 | console.log({} > {}); 251 | console.log({} >= {}); 252 | console.log({} == {}); 253 | ``` 254 | 255 | - 23- Chained comparison operators 256 | 257 | ```jsx 258 | console.log(1 < 2 < 3); 259 | console.log(3 > 2 > 1); 260 | console.log(3 > 2 > 0); 261 | ``` 262 | 263 | - 24- Reference vs reassignment 264 | 265 | ```jsx 266 | let x = [1, 2, 3]; 267 | let y = x; 268 | x = [4, 5, 6]; 269 | console.log(y); 270 | ``` 271 | 272 | - 25- Array length with sparse arrays 273 | 274 | ```jsx 275 | const numbers = [1, 2, 3]; 276 | numbers[10] = 10; 277 | console.log(numbers.length); 278 | ``` 279 | 280 | - 26- delete operator return values 281 | 282 | ```jsx 283 | let x = { y: 1 }; 284 | console.log(delete x.y); 285 | console.log(delete x.z); 286 | ``` 287 | 288 | - 27- Object coercion precedence (valueOf vs toString) 289 | 290 | ```jsx 291 | const obj = { 292 | valueOf() { return 1; }, 293 | toString() { return '2'; } 294 | }; 295 | console.log(+obj); 296 | console.log(`${obj}`); 297 | console.log(obj + '3'); 298 | ``` 299 | 300 | - 28- Array coercion with spread operator 301 | 302 | ```jsx 303 | const arr1 = [1, 2]; 304 | const arr2 = [3, 4]; 305 | console.log(arr1 + arr2); 306 | console.log([...arr1] + [...arr2]); 307 | console.log(+[...arr1, ...arr2]); 308 | ``` 309 | 310 | - 29- Function object coercion 311 | 312 | ```jsx 313 | function fn() {} 314 | fn.toString = () => '1'; 315 | fn.valueOf = () => 2; 316 | console.log(fn + 1); 317 | console.log(`${fn}`); 318 | console.log(+fn); 319 | ``` 320 | 321 | - 30- Array with custom toString 322 | 323 | ```jsx 324 | const arr = ['1', '2', '3']; 325 | arr.toString = () => '4'; 326 | console.log(+arr); 327 | console.log([...arr] + []); 328 | console.log(arr + '5'); 329 | ``` 330 | 331 | - 31- Constructor function without new 332 | 333 | ```jsx 334 | function User() { 335 | this.name = "John"; 336 | } 337 | const user = User(); 338 | console.log(user?.name); 339 | ``` 340 | 341 | - 32- Unreachable code after return 342 | 343 | ```jsx 344 | function greet(name) { 345 | return `Hello ${name}!` 346 | console.log("This won't run"); 347 | } 348 | console.log(greet("John")); 349 | ``` 350 | 351 | - 33- Duplicate parameter names 352 | 353 | ```jsx 354 | function sum(a, a, c) { 355 | return a + a + c; 356 | } 357 | console.log(sum(1, 2, 3)); 358 | ``` 359 | 360 | - 34- Automatic semicolon insertion 361 | 362 | ```jsx 363 | function test(x) { 364 | return 365 | { 366 | value: x 367 | } 368 | } 369 | console.log(test(1)); 370 | ``` 371 | 372 | - 35- Optional chaining returns undefined 373 | 374 | ```jsx 375 | const obj = { 376 | prop: 'exists' 377 | }; 378 | console.log(obj.prop1?.prop2); 379 | ``` 380 | 381 | - 36- String padding default behavior 382 | 383 | ```jsx 384 | const name = "John"; 385 | console.log(`Hello ${name.padEnd(10)}`); 386 | ``` 387 | 388 | - 37- Nullish coalescing operator 389 | 390 | ```jsx 391 | console.log(undefined ?? "default"); 392 | console.log(null ?? "default"); 393 | console.log("" ?? "default"); 394 | ``` 395 | 396 | - 38- Increment operator type conversion 397 | 398 | ```jsx 399 | let x = "5"; 400 | let y = 5 ; 401 | console.log(++x); 402 | console.log(++y); 403 | ``` 404 | 405 | - 39- Array Methods Return Values and Mutations 406 | 407 | ```jsx 408 | function arrayMagic(...args) { 409 | let result = args.push(args.pop()); 410 | result += args.unshift(result); 411 | return args.push(result); 412 | } 413 | 414 | console.log(arrayMagic(1, 2, 3)); 415 | console.log(arrayMagic(1)); 416 | console.log(arrayMagic()); 417 | ``` 418 | 419 | - 40- Promise + setTimeout + Event Loop 420 | 421 | ```jsx 422 | console.log('start'); 423 | Promise.resolve().then(() => { 424 | setTimeout(() => { 425 | console.log('timeout'); 426 | }, 0); 427 | console.log('promise'); 428 | }); 429 | setTimeout(() => { 430 | console.log('timeout2'); 431 | }, 0); 432 | console.log('end'); 433 | ``` 434 | 435 | - 41- Event Loop and closure value capture 436 | 437 | ```jsx 438 | let i = 0; 439 | setTimeout(() => console.log(i), 0); 440 | i++; 441 | ``` 442 | 443 | - 42- var in loops with setTimeout 444 | 445 | ```jsx 446 | for(var i = 0; i < 3; i++) { 447 | setTimeout(() => console.log(i), 1000); 448 | } 449 | ``` 450 | 451 | - 43- async/await + setTimeout + Promise 452 | 453 | ```jsx 454 | async function foo() { 455 | console.log(1); 456 | setTimeout(() => console.log(2), 0); 457 | await Promise.resolve().then(() => console.log(3)); 458 | console.log(4); 459 | } 460 | foo(); 461 | console.log(5); 462 | ``` 463 | 464 | - 44- async forEach + Promise resolution 465 | 466 | ```jsx 467 | const arr = [1, 2, 3]; 468 | arr.forEach(async (num) => { 469 | await new Promise(resolve => 470 | setTimeout(resolve, 1000) 471 | ); 472 | console.log(num); 473 | }); 474 | console.log('done'); 475 | ``` 476 | 477 | - 45- setInterval + Promise + Closure 478 | 479 | ```jsx 480 | let count = 0; 481 | const interval = setInterval(() => { 482 | Promise.resolve().then(() => console.log(++count)); 483 | if(count > 2) clearInterval(interval); 484 | }, 0); 485 | ``` 486 | 487 | - 46- Promise reuse + setTimeout + Callback 488 | 489 | ```jsx 490 | const promise = new Promise(resolve => { 491 | setTimeout(() => resolve('first'), 1000); 492 | }); 493 | promise.then(console.log); 494 | promise.then(console.log); 495 | ``` 496 | 497 | - 47- this context + async/await + Closure 498 | 499 | ```jsx 500 | let obj = { 501 | async method() { 502 | let that = this; 503 | await Promise.resolve(); 504 | return () => { 505 | console.log(this === that); 506 | }; 507 | } 508 | }; 509 | obj.method().then(fn => fn()); 510 | ``` 511 | 512 | - 48- async/await + Variable Mutation + Execution Order 513 | 514 | ```jsx 515 | let x = 0; 516 | async function increment() { 517 | x++; 518 | await Promise.resolve(); 519 | x++; 520 | return x; 521 | } 522 | increment(); 523 | increment(); 524 | console.log(x); 525 | ``` 526 | 527 | - 49- Error Handling + Event Loop + Multiple Async Operations 528 | 529 | ```jsx 530 | const fn = async () => { 531 | await Promise.resolve(); 532 | throw new Error('oops'); 533 | }; 534 | fn().catch(console.log); 535 | setTimeout(() => console.log('timeout'), 0); 536 | Promise.resolve().then(() => console.log('promise')); 537 | ``` 538 | 539 | - 50- Custom Promise + async/await + Return Value 540 | 541 | ```jsx 542 | function delay(ms) { 543 | return new Promise(resolve => setTimeout(resolve, ms)); 544 | } 545 | async function sequence() { 546 | console.log(1); 547 | await delay(1000); 548 | console.log(2); 549 | return Promise.resolve(3); 550 | } 551 | sequence().then(console.log); 552 | console.log(4); 553 | ``` 554 | 555 | - 51- Nested array access with coercion 556 | 557 | ```jsx 558 | console.log([[]][+[]] + []); 559 | console.log([[]][!+[]] + []); 560 | console.log([[]] + [![]]); 561 | ``` 562 | 563 | - 52- Parallel Promises + Dynamic Timeouts + forEach async 564 | 565 | ```jsx 566 | const array = [1, 2, 3]; 567 | array.forEach(async (num) => { 568 | await new Promise(r => setTimeout(r, 3 - num)); 569 | console.log(num); 570 | }); 571 | Promise.resolve().then(() => console.log('done')); 572 | ``` 573 | 574 | - 53- ALL async Concepts 575 | 576 | ```jsx 577 | console.log('1'); // Sync 578 | 579 | setTimeout(() => console.log('2'), 0); // Macro 580 | 581 | const promise = new Promise(resolve => { 582 | console.log('3'); // Sync 583 | resolve('4'); 584 | console.log('5'); // Sync 585 | }).then(msg => { 586 | console.log(msg); // Micro 587 | Promise.resolve('6').then(msg => console.log(msg)) // Micro 588 | }); 589 | 590 | async function test() { 591 | console.log('7'); // Sync 592 | await Promise.resolve('8'); 593 | console.log('9'); // Micro 594 | } 595 | 596 | test(); 597 | console.log('10'); // Sync 598 | ``` 599 | 600 | - 54- ALL Falsy/Truthy Values 601 | 602 | ```jsx 603 | // Part 1: Comparison chains 604 | console.log(null == undefined > 0); // Tests: null==undefined, undefined>0 605 | console.log("" == false == 0); // Tests: string==boolean==number 606 | console.log(NaN !== NaN < true); // Tests: NaN self-comparison, boolean conversion 607 | 608 | // Part 2: Mixed operations 609 | console.log(+null + "" + false); // Tests: null to number, string concat 610 | console.log(!"" + +undefined + []); // Tests: empty string to boolean, undefined to number 611 | console.log(typeof NaN + Boolean(0)); // Tests: typeof NaN, explicit boolean conversion 612 | 613 | // Part 3: Object conversions 614 | console.log([null] == "null"); // Tests: array with null to string 615 | console.log([undefined] == false); // Tests: array with undefined coercion 616 | ``` 617 | 618 | - 55- JavaScript Number Boundaries and Special Values 619 | 620 | ```jsx 621 | 622 | // Part 1: Boundary Comparisons 623 | console.log(Number.MAX_VALUE + Number.MAX_VALUE); // Infinity 624 | console.log(Number.MAX_VALUE > Infinity); // false 625 | console.log(-Number.MAX_VALUE < -Infinity); // false 626 | console.log(Number.MIN_VALUE + Number.MIN_VALUE); // Still positive! 627 | 628 | // Part 2: Safe Integer Edge Cases 629 | console.log(Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2); // true! 630 | console.log(Number.MAX_SAFE_INTEGER + 1.1); // Precision loss 631 | console.log(Math.pow(2, 53) === Math.pow(2, 53) + 1); // true, beyond safe 632 | 633 | // Part 3: Special Operations 634 | console.log(Infinity / Infinity); // NaN 635 | console.log(Number.MIN_VALUE / 2); // Underflow behavior 636 | console.log(Number.MAX_VALUE * Number.MIN_VALUE); // Interesting result 637 | ``` 638 | 639 | --- 640 | 641 | ## 🚀 Contributing 642 | 643 | Want to add your own tricky JavaScript question or debugging challenge? **Contributions are welcome!** 644 | 645 | 1. Fork the repository 646 | 2. Create a new branch (`feature/my-question`) 647 | 3. Add your tricky question with an explanation 648 | 4. Submit a Pull Request 🚀 649 | 650 | --- 651 | 652 | ## 📢 Spread the Word 653 | 654 | If you found this repo useful, **give it a ⭐ and share it with others!**\ 655 | Happy coding! 🚀🔥 656 | 657 | --------------------------------------------------------------------------------