├── .gitignore ├── README.md └── images └── logo.jpeg /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

JavaScript tips & tricks

2 | 3 | 4 |
5 | 6 |
7 | 8 | # Description 😋 9 | 10 | > This is a collection of JavaScript tips and tricks. you can refer to it and apply it to make your code more concise. **But don't overdo it**, it can make your code difficult to read and maintain. Hope everyone contributes, thanks. 11 | 12 | 13 | 14 | # Table Of Content 📃 15 | 16 | - [Description](#description) 17 | - [Table Of Content](#table-of-content) 18 | - [Array](#array) 19 | - [Object](#object) 20 | - [Destructuring](#destructuring) 21 | - [Operator](#operator) 22 | - [Comparison](#comparison) 23 | - [Others](#others) 24 | 25 | 26 | 27 | # Array 28 | 29 |
30 | 31 | 1. Generate an Array 32 | 33 | 34 | - Create an empty array of length **`n`** 35 | 36 | ```js 37 | var arr = new Array(3); 38 | 39 | // result: arr = [undefined, undefined, undefined] 40 | ``` 41 | 42 | - Create an empty array of length **`n`** & fill value **`x`** 43 | 44 | ```js 45 | var arr = [...Array(3).fill(1)]; 46 | var arr2 = [...Array(5).fill(1, 0, 3)]; 47 | 48 | /* 49 | result: arr = [1, 1, 1] 50 | arr2 = [1, 1, 1, undefined, undefined] 51 | */ 52 | ``` 53 | 54 | - Create an array containing `0...n` 55 | 56 | ```js 57 | var arr = [...Array.keys(5)]; 58 | 59 | // result: arr = [0, 1, 2, 3, 4] 60 | ``` 61 | 62 | - Create an array containing `1...n` 63 | 64 | ```js 65 | var arr = []; 66 | for (let i = 0; arr.push(++i) < 4; ); 67 | 68 | var arr2 = Array.from({ length: 4 }, (_, i) => i + 1); 69 | var arr3 = Array.from({ length: 4 }, (_, i) => i * 2); 70 | var arr4 = Array.from({ length: 4 }, () => Math.random()); 71 | 72 | /* 73 | result: arr = [1, 2, 3, 4] 74 | arr2 = [1, 2, 3, 4] 75 | arr3 = [0, 2, 4, 6] 76 | arr4 = [0.211, 0.5123, 0.612, 0.8921] 77 | */ 78 | ``` 79 | 80 |
81 | 82 |
83 | 84 | 2. Extract Unique Values of Array 85 | 86 | 87 |
88 | 89 | ```js 90 | var arr = [1, 2, 2, 3, 5, 5, 4]; 91 | var newArr = [...new Set(arr)]; 92 | 93 | // result: newArr = [1, 2, 3, 5, 4] 94 | ``` 95 | 96 |
97 | 98 |
99 | 100 | 3. Shuffle Elements from Array 101 | 102 | 103 |
104 | 105 | ```js 106 | var arr = [1, 2, 3, 4, 5]; 107 | var newArr = arr.sort(() => Math.random() - 0.5); 108 | 109 | // result: newArr = [3, 1, 2, 4, 5] 110 | ``` 111 | 112 |
113 | 114 |
115 | 116 | 4. Flatten a Multidimensional Array 117 | 118 | 119 |
120 | 121 | ```js 122 | var arr = [1, [2, 3], [4, 5, 6], 7]; 123 | var newArr = [].concat(...arr); 124 | 125 | // result: [1, 2, 3, 4, 5, 6, 7] 126 | ``` 127 | 128 |
129 | 130 |
131 | 132 | 5. Resize an Array 133 | 134 | 135 | > The length array isn't a read only property. 136 | 137 | ```js 138 | var arr = [1, 2, 3, 4, 5]; 139 | arr.length = 2; 140 | 141 | var arr2 = [1, 2, 3, 4, 5]; 142 | arr2.length = 0; 143 | 144 | var arr3 = [1, 2, 3, 4, 5]; 145 | arr3.length = 7; 146 | 147 | /* 148 | result: arr = [1, 2] 149 | arr2 = [] 150 | arr3 = [1, 2, 3, 4, 5, undefined, undefined] 151 | */ 152 | ``` 153 | 154 |
155 | 156 |
157 | 158 | 6. Random an Item in Array 159 | 160 | 161 |
162 | 163 | ```js 164 | var arr = [2, 4, 5]; 165 | var item = arr[Math.floor(Math.random() * arr.length)]; 166 | ``` 167 | 168 |
169 | 170 |
171 | 172 | 7. Remove an Item from Array 173 | 174 | 175 |
176 | 177 | ```js 178 | var arr = [1, 2, 3]; 179 | 180 | // Not Recommended 181 | delete arr[1]; // arr = [1, undefined, 3], length = 3 182 | 183 | // Recommended 184 | arr.splice(1, 1); // arr = [1, 3], length = 2 185 | ``` 186 | 187 |
188 | 189 | # Object 190 | 191 |
192 | 193 | 1. Dynamic Property Name 194 | 195 | 196 |
197 | 198 | ```js 199 | const dynamic = 'age', 200 | dynamicValue = 18; 201 | 202 | var obj = { 203 | name: 'Dyno', 204 | [dynamic]: dynamicValue, 205 | }; 206 | 207 | // result: obj = { name: 'Dyno', age: 18 } 208 | ``` 209 | 210 |
211 | 212 |
213 | 214 |
215 | 216 | 2. Clone an Object 217 | 218 | 219 | - Shallow copy `(Not Recommended)` 220 | 221 | > Use the `=` operator to copy object 1 into object 2. These 2 objects point to the same memory area `(reference)`. Therefore, if we change object 1, object 2 will also change. 222 | 223 | ```js 224 | var obj1 = { a: 1, b: 2 }; 225 | var obj2 = obj1; // obj2 = { a: 1, b: 2 } 226 | 227 | obj1.a = 3; // change value of a property 228 | 229 | console.log(obj1); // { a: 3, b: 2 } 230 | console.log(obj2); // { a: 3, b: 2 } => property a of obj2 changed 🙂❗ 231 | console.log(obj3); // { a: 3, b: 2 } => property a of obj2 changed 🙂❗ 232 | ``` 233 | 234 | - Deep copy 235 | 236 | > **Way 1**: Use Spread operator `{...}` or `Object.assign()` to fix "Shallow copy". **_Issue:_** `Nested objects` still have shallow copy problem. 237 | 238 | ```js 239 | var obj1 = { a: 1, b: 2, c: { nested: 3 } }; 240 | var obj2 = { ...obj1 }; // obj2 = { a: 1, b: 2, c: { nested: 3 } } 241 | var obj3 = Object.assign({}, obj1); // obj3 = { a: 1, b: 2, c: { nested: 3 } } 242 | 243 | obj1.b = 3; 244 | obj1.c.nested = 4; 245 | 246 | console.log(obj1); // { a: 1, b: 3, c: { nested: 4 } } 247 | console.log(obj2); // { a: 1, b: 2, c: { nested: 4 } } 🙂 248 | console.log(obj3); // { a: 1, b: 2, c: { nested: 4 } } 🙂 249 | ``` 250 | 251 | > **Way 2 `(Recommended)`**: Use `JSON.stringify()` & `JSON.parse()` to solve the above problems. 252 | 253 | ```js 254 | var obj1 = { a: 1, b: 2, c: { nested: 3 } }; 255 | var obj2 = JSON.parse(JSON.stringify(obj1)); // obj2 = { a: 1, b: 2, c: { nested: 3 } } 256 | 257 | obj1.b = 3; 258 | obj1.c.nested = 4; 259 | 260 | console.log(obj1); // { a: 1, b: 3, c: { nested: 4 } } 261 | console.log(obj2); // { a: 1, b: 2, c: { nested: 3 } } 😉😘 262 | ``` 263 | 264 |
265 | 266 |
267 | 268 | # Destructuring (ES6+) 269 | 270 |
271 | 272 | 1. With Array 273 | 274 | 275 |
276 | 277 | ```js 278 | var [a, b] = [1, 2]; 279 | // same: var a = 1, b = 2; 280 | 281 | var [a, b, c] = [1, 2, 3, 4, 5]; 282 | // same: var a = 1, b = 2, c = 3; 283 | 284 | var [a, , c] = [1, 2, 3, 4, 5]; 285 | // same: var a = 1, c = 3 286 | // ignore values 287 | 288 | var [a, b, ...rest] = [1, 2, 3, 4, 5]; 289 | // same: var a = 1, b = 2, rest = [4, 5] 290 | // use "rest params ES6" 291 | 292 | var [a, b, c] = [1, 2]; 293 | // same: var a = 1, b = 2, c = undefined; 294 | 295 | var [a, b = 0, c = 0] = [1, 2]; 296 | // same: var a = 1, b = 2, c = 0; 297 | // declare and set default value 298 | 299 | var [a, b, [c, d], e] = [1, 2, [3, 4], 5]; 300 | // same: var a = 1, b = 2, c = 3, d = 4, e = 5 301 | // nested array destructuring 302 | ``` 303 | 304 |
305 | 306 |
307 | 308 | 2. With Object 309 | 310 | 311 |
312 | 313 | ```js 314 | var person = { name: 'Dyno', age: 18 }; 315 | 316 | var { name, age } = person; 317 | // same: var name = person.name, age = person.age; 318 | 319 | var { name = 'Anonymous', age = 1, address = 'HCM city' } = person; 320 | // same: var name = person.name, age = person.age, address: 'HCM city' 321 | // declare and set default value 322 | 323 | var { name: personName, age: personAge } = person; 324 | // same: var personName = person.name, personAge = person.age 325 | // decleare and change variable name 326 | 327 | console.log({ name, age }); 328 | // same: console.log({ name: name, age: age }) 329 | 330 | var person = { name: 'Dyno', age: 18, infor: { address: 'HCM', phone: '123' } }; 331 | var { 332 | name, 333 | age, 334 | infor: { address, phone }, 335 | } = person; 336 | // same: name = person.name, age = person.agem, address = person.infor.address, phone = person.infor.phone 337 | // nested object destructuring 338 | ``` 339 | 340 |
341 | 342 | # Operator 343 | 344 |
345 | 346 | 1. Optional chaining (?.) 347 | 348 | 349 |
350 | 351 | > "The optional chaining operator `?.` enables you to read the value of a property located deep within a chain of connected objects without having to check that each reference in the chain is valid." [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining) 352 | 353 |
354 | 355 | ```js 356 | const person = { 357 | name: 'Dyno', 358 | age: 18, 359 | sayHello: function () { 360 | console.log('Hello'); 361 | }, 362 | }; 363 | 364 | // ❗ Wrong way 365 | console.log(person.infor.address); // ❌ Uncaught TypeError: Cannot read property 'address' of undefined 366 | 367 | // ✅ Right way (check condition) 368 | if (person.infor) console.log(person.infor.address); // Not log 369 | 370 | // ✅ Right way (use ?.) 371 | console.log(person.infor?.address); // undefined 372 | 373 | // Optional chaining with function calls 374 | console.log(person.sayHello?.()); // Hello 375 | console.log(person.callPhone?.()); // undefined 376 | 377 | // A chain Optional chaining 378 | console.log(person.infor?.address?.province?.name); // undefined 379 | ``` 380 | 381 | ```js 382 | // syntax 383 | obj.val?.prop; 384 | obj.val?.[expr]; 385 | obj.arr?.[index]; 386 | obj.func?.(args); 387 | ``` 388 | 389 |
390 | 391 |
392 | 393 | 2. Nullish coalescing operator (??) 394 | 395 | 396 |
397 | 398 | > "The nullish coalescing operator `??` is a logical operator that returns its right-hand side operand when its left-hand side operand is `null` or `undefined`, and otherwise returns its left-hand side operand." [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator) 399 | 400 | ```js 401 | var a = null ?? 'Default'; // a = 'Default' 402 | var a = false ?? 'Default'; // a = false 403 | ``` 404 | 405 |
406 | 407 |
408 | 409 | 3. Logical OR (||) 410 | 411 | 412 | ```js 413 | var a = 1, 414 | b = 2; 415 | 416 | if (a > 2 || b > 1) console.log('Dyno'); 417 | 418 | // result: Dyno 419 | ``` 420 | 421 | > The OR operator `||` is a logical operator that returns its right-hand side operand when its left-hand side operand is `falsy`, and otherwise returns its left-hand side operand. 422 | 423 |
424 | 425 | ```js 426 | var a = null || 'Default'; // a = 'Default' 427 | var a = false || 'Default'; // a = 'Default' 428 | ``` 429 | 430 |
431 | 432 |
433 | 434 | 4. Logical AND (&&) 435 | 436 | 437 |
438 | 439 | ```js 440 | let a = true, 441 | b = true, 442 | c = false; 443 | 444 | if (a && b) console.log('Hello'); // Hello (a, b = true) 445 | 446 | if (a && c) console.log('Dyno'); // not log (c = false) 447 | 448 | // other usage 449 | function sayHi() { 450 | console.log('Hi'); 451 | } 452 | 453 | a && sayHi(); // Hi 454 | c && sayHi(); // false 455 | ``` 456 | 457 |
458 | 459 |
460 | 461 | 5. Double tilde operator (~~) 462 | 463 | 464 |
465 | 466 | ```js 467 | let num = 2.6; 468 | console.log(~~num); // 2 = Math.floor(2) 469 | ``` 470 | 471 |
472 | 473 |
474 | 475 | 6. Logical Assignment Operator ES12 (||=, ??=) 476 | 477 | 478 |
479 | 480 | ```js 481 | a ||= b; // same a = a || b; 482 | a ??= b; // same a = a ?? b; 483 | ``` 484 | 485 |
486 | 487 |
488 | 489 | 7. Numeric separator ES12 (_) 490 | 491 | 492 |
493 | 494 | ```js 495 | const n = 1_000_000_000; // same: n = 1000000000; 496 | ``` 497 | 498 |
499 | 500 | # Comparison 501 | 502 |
503 | 504 | 1. Use === instead of == 505 | 506 | 507 |
508 | 509 | > The operator `== (!=)` will automatically cast if 2 variables are not of the same type, then compare. The `=== (!==)` operator compares the value and the type => `===` faster than `==`. 510 | 511 |
512 | 513 | ```js 514 | 1 == '1' // true 515 | 1 === '1' // false 516 | 517 | 0 == false // true 518 | 0 === false // false 519 | 520 | '' == false // true 521 | '' === false // false 522 | 523 | [] == 0 // true 524 | [] === 0 // false 525 | 526 | ``` 527 | 528 |
529 | 530 |
531 | 532 | 2. The difference between isNaN() and Number.isNaN() 533 | 534 | 535 |
536 | 537 | > The `isNaN()` method (is Not a Number ?) use to check if a variable is **a Number**. The `Number.isNaN()` (is NaN ?) method use to check if a variable is **NaN** 538 | 539 |
540 | 541 | ```js 542 | isNaN('string'); 543 | // true, 'string' is not Number 544 | 545 | isNaN([]); 546 | // true, [] is not Number 547 | 548 | isNaN(0 / 0); 549 | // true, 0/0 is not Number 550 | 551 | isNaN(1); 552 | // false, 1 is Number 553 | 554 | Number.isNaN('string'); 555 | // false, 'string' is not NaN 556 | 557 | Number.isNaN([]); 558 | // false, [] is not NaN 559 | 560 | Number.isNaN(0 / 0); 561 | // true, 0/0 is NaN 562 | 563 | Number.isNaN(NaN); 564 | // true 565 | ``` 566 | 567 |
568 | 569 | # Others 570 | 571 |
572 | 573 | 574 | 1. Swapping use Destructuring 575 | 576 | 577 |
578 | 579 | ```js 580 | let a = 1, 581 | b = 2; 582 | 583 | [a, b] = [b, a]; 584 | 585 | // result: a = 2, b = 1; 586 | ``` 587 | 588 |
589 | 590 |
591 | 592 | 2. Create function that returns only 1 object 593 | 594 | 595 |
596 | 597 | ```js 598 | const fn = () => ({ obj: 1 }); 599 | 600 | /* 601 | same: const fn = () => { 602 | return { obj: 1 } 603 | } 604 | */ 605 | ``` 606 | 607 |
608 | 609 |
610 | 611 | 3. Immediately Invoked Function Expression (IIFE) 612 | 613 | 614 |
615 | 616 | > The function will execute automatically when you create it. 617 | 618 |
619 | 620 | ```js 621 | // Way 1: 622 | var res = ()(function(){ 623 | // do something... 624 | console.log("Hello"); 625 | return true; 626 | })(); 627 | // result: Hello, res = true; 628 | 629 | // Way 2: 630 | var res = (() => { 631 | console.log('Hello'); 632 | return true; 633 | })(); 634 | // result: Hello, res = true; 635 | ``` 636 | 637 |
638 | 639 |
640 | 641 | 4. typeof vs instanceof 642 | 643 | 644 |
645 | 646 | > `typeof`: return a string that represents the primitive type of a variable. 647 | 648 | > `instanceof`: check in all the prototypes chain the constructor it returns true if it’s found and false if not. 649 | 650 |
651 | 652 | ```js 653 | var arr = [1, 2, 3]; 654 | console.log(typeof arr); // "object" 655 | console.log(arr instanceof Array); // true 656 | 657 | typeof 1; // "number" 658 | typeof NaN; // "number" 659 | typeof 'str'; // "string" 660 | typeof true; // "boolean" 661 | typeof {}; // "object" 662 | typeof []; // "object" 663 | typeof null; // "object" 664 | typeof undefined; // "undefined" 665 | typeof function name() {}; // "function" 666 | ``` 667 | 668 |
669 | 670 |
671 | 672 | 5. Falsy 673 | 674 | 675 |
676 | 677 | > A `Falsy value` is a value that is considered false when encountered in a Boolean context . [MDN](https://developer.mozilla.org/en-US/docs/Glossary/Falsy) 678 | 679 | > Complete list of JavaScript falsy values ` false, 0, -0, 0n, "", '', ``, NaN, null, undefined, document.all` 680 | 681 | > Falsy value bypass the if block. Ex: 682 | 683 |
684 | 685 | ```js 686 | if (null) { 687 | } else { 688 | console.log('Falsy'); 689 | } 690 | 691 | const a = undefined || 'Falsy'; 692 | 693 | // result: Falsy, a = "Falsy" 694 | ``` 695 | 696 | > Filter out Falsy values 697 | 698 |
699 | 700 | ```js 701 | const arr = [1, 'Dyno', false, 0, true, NaN, 2000]; 702 | var filteredArr = arr.filter(Boolean); 703 | 704 | // result: filteredArr = [1, "Dyno", true, 2000] 705 | ``` 706 | 707 |
708 | 709 |
710 | 711 | 6. Template string `${}` 712 | 713 | 714 |
715 | 716 | ```js 717 | const name = 'Dyno'; 718 | const hello1 = 'Hello ' + name + ', how are you?'; 719 | const hello2 = `Hello ${name}, how are you?`; // template string. 720 | ``` 721 | 722 |
723 | 724 |
725 | 726 | 7. Rounding number to n decimal place 727 | 728 | 729 | 730 |
731 | 732 | ```js 733 | var num = 25.0420001; 734 | console.log(typeof num); // "number" 735 | 736 | num = num.toFixed(2); // num = "25.04" 737 | console.log(typeof num); // ❗ "string" 738 | ``` 739 | 740 |
741 | 742 |
743 | 744 | 8. Check variable - convert a variable to Boolean (!! operator) 745 | 746 | 747 |
748 | 749 | ```js 750 | console.log(!!null); // false 751 | console.log(!!undefined); // false 752 | console.log(!!1); // true 753 | ``` 754 | 755 |
756 | -------------------------------------------------------------------------------- /images/logo.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dynonguyen/javascript-tips/9df0b4e224e120d6df43194a87de240691330c4b/images/logo.jpeg --------------------------------------------------------------------------------