โโโ README.md
/README.md:
--------------------------------------------------------------------------------
1 | # Table of Contents
2 |
3 | 1. [JavaScript: Getting Started ๐ฅ](#javascript-getting-started-)
4 | 2. [JavaScript: Data types and variables ๐ฅ](#javascript-data-types-and-variables-)
5 | 3. [JavaScript: Execution Context โญ](#javascript-execution-context-)
6 | 4. [JavaScript Hoisting - Explained EASILY](#javascript-hoisting---explained-easily)
7 | 5. [JavaScript: Function Declaration vs Function Expression and Much More๐ฅ](#javascript-function-declaration-vs-function-expression-and-much-more)
8 | 6. [JavaScript: undefined vs Not defined๐ฅ](#javascript-undefined-vs-not-defined)
9 | 7. [JavaScript: Scope and Lexical Scope ๐ฅ](#javascript-scope-and-lexical-scope-)
10 | 8. [JavaScript: Types of Errors ๐คก](#javascript-types-of-errors-)
11 | 9. [JavaScript: Block Scope & Shadowing๐ฅ](#javascript-block-scope--shadowing)
12 | 10. [JavaScript: Closures ๐ฅ](#javascript-closures-)
13 | 11. [JavaScript: Callback Functions ๐ฅ](#javascript-callback-functions-)
14 | 12. [JavaScript: Working of Async Code ๐ฅ](#javascript-working-of-async-code-)
15 | 13. [How JavaScript Engine Works ๐๐จ](#how-javascript-engine-works-)
16 | 14. [JavaScript: Callbacks Problems ๐ฅ](#javascript-callbacks-problems-)
17 | 15. [JavaScript: Promises ๐ฅ](#javascript-promises-)
18 | 16. [JavaScript: Promise APIs ๐ฅ๐ฅ](#javascript-promise-apis-)
19 | 17. [JavaScript: Async/Await ๐ฅ](#javascript-asyncawait-)
20 | 18. [JavaScript: `this` keyword ๐ฅ](#javascript-this-keyword-)
21 | 19. [JavaScript: "use strict" ๐ฅ](#javascript-use-strict-)
22 | 20. [JavaScript: call(), apply(), bind() ๐ฅ](#javascript-call-apply-bind-)
23 | 21. [JavaScript: Currying ๐ ๐ฅ](#javascript-currying--)
24 | 22. [JavaScript: Prototype ๐ฅ๐ฅ](#javascript-prototype-)
25 | 23. [JavaScript: OOP Introduction๐ฅ](#javascript-oop-introduction)
26 | 24. [JavaScript: Inheritance ๐ฅ๐จโ๐ฆ](#javascript-inheritance-)
27 | 25. [JavaScript: Abstraction and Encapsulation ๐ฅ](#javascript-abstraction-and-encapsulation-)
28 | 26. [JavaScript: Static Properties and Methods ๐ฅ](#javascript-static-properties-and-methods-)
29 | 27. [JavaScript: Event Bubbling & Capturing ๐ฅ](#javascript-event-bubbling--capturing-)
30 | 28. [JavaScript: Event Delegation ๐ฅ](#javascript-event-delegation-)
31 | 29. [JavaScript: Script Loading ๐ฅ](#javascript-script-loading-)
32 | 30. [JavaScript: Coercion ๐ฅ๐ฅ๐ฅ](#javascript-coercion-)
33 | 31. [JavaScript: Coercion Day 2 ๐ฅ๐ฅ](#javascript-coercion-day-2-)
34 | 32. [JavaScript: Coercian Day 3 ๐ฅ๐ฅ](#javascript-coercian-day-3-)
35 | 33. [JavaScript: Coercion Last Day ๐ฅ๐ฅ๐ฅ](#javascript-coercion-last-day-)
36 | 34. [JavaScript: == ๐ ===](#javascript---)
37 | 35. [JavaScript: NaN (Not a Number) ๐ฅต](#javascript-nan-not-a-number-)
38 | 36. [Debouncing and Throttling ๐ฅ](#-debouncing-and-throttling-)
39 | 37. [How to loop over objects? ๐ค๐](#how-to-loop-over-objects-)
40 |
41 |
42 | # JavaScript: Getting Started ๐ฅ
43 |
44 | ## Introduction to ECMAScript
45 |
46 | Before diving into JavaScript, let's get acquainted with ECMAScript, the standard on which JavaScript is based.
47 |
48 | ### Versions of ECMAScript
49 |
50 | - **ES1** - 1997 (First release)
51 | - โญ **ES6** - 2015 (Major changes introduced)
52 | - **ES13** - 2022 (Latest version)
53 |
54 | ## What is JavaScript?
55 |
56 | JavaScript is a versatile scripting language primarily used for web development. Here's a brief overview:
57 |
58 | - **Purpose**: Used to add interactivity and dynamic effects to web pages.
59 | - **File Extension**: `.js`
60 | - **Usage**: Initially designed for client-side development, but now also used in server-side development.
61 | - **Typing**: Dynamically typed (no need to specify data types).
62 | - **Concurrency Model**: Asynchronous single-threaded language.
63 |
64 | ### Frameworks and Libraries
65 |
66 | - **Frontend Frameworks**: React, Angular, Vue, etc.
67 | - **Backend Frameworks**: Express, Node.js
68 |
69 | ## JavaScript Engine
70 |
71 | To run JavaScript, we need a JavaScript engine that executes and compiles JS into native machine code.
72 |
73 | ### Common JavaScript Engines
74 |
75 | - **Chrome**: V8
76 | - **Firefox**: SpiderMonkey
77 | - **Safari**: JavaScriptCore
78 | - **Edge (IE)**: Chakra
79 |
80 | ## Running JavaScript Outside the Browser
81 |
82 | JavaScript can be executed outside the browser using Node.js.
83 |
84 | ### Node.js
85 |
86 | Node.js is an open-source, cross-platform JavaScript runtime environment that executes JavaScript code outside of a web browser. It's commonly used for:
87 |
88 | - Server-side applications
89 | - Command-line tools
90 | - Scalable network programs
91 |
92 | ---
93 |
94 | This guide provides a brief introduction to JavaScript and its related technologies. For a deeper dive, consider exploring each topic in more detail.
95 |
96 | # JavaScript: Data types and variables ๐ฅ
97 |
98 | Variables are like a container that store some data.
99 |
100 | In JavaScript we can declare variables in three ways that is using var, let, and const.
101 |
102 | General Rules for variable names:
103 | - cannot start with a number
104 | - names are case sensitive
105 | - names can only contains letters, digits and underscores _
106 |
107 |
108 |
109 | ## Data Types
110 |
111 | In JavaScript we can classify data types in two types
112 |
113 | 1. Primitive Data Types [ simple ]
114 | - Numbers
115 | - Strings
116 | - Booleans
117 | - Null
118 | - Undefined
119 | - Big Int
120 | - Symbol
121 |
122 | 2. Objects:
123 | - Object stores data in key-value pairs
124 | - They are mutable (can be modified)
125 | - Considered as complex Data structure
126 | [ Example: Object, Array, Date Object ]
127 |
128 |
129 | ## ๐ฅ var vs let vs const ๐ฅ
130 |
131 | **var**
132 | - introduced in early days
133 | - limitations: it is function scoped not block scoped
134 |
135 | Means - variables are accessible within entire function in which they are declared, rather than just within the block of code they appear
136 |
137 |
138 | **let**
139 | - introduced in es6
140 | - block scoped
141 | - value can be reassigned
142 |
143 | **const**
144 | - introduced in es6
145 | - block scoped
146 | - value can not be reassigned
147 | - must assign value while declaration
148 |
149 | 
150 |
151 |
152 | # JavaScript: Execution Context โญ
153 |
154 | When the JS engine scans code, it creates an environment called the Execution Context.
155 |
156 | ## Types of Execution Context
157 |
158 | 1. **Global EC**: Created when JS code first starts to run and represents the global scope in JS.
159 | 2. **Function EC**: Created when a function in the code starts executing.
160 |
161 | ## Execution Phases
162 |
163 | ### 1. Memory Creation Phase
164 | - Allocates location to variables and functions.
165 | - Stores variables with value as `undefined` and function references (i.e., the complete function definition).
166 |
167 | ### 2. Execution Phase
168 | - Starts through the entire code line by line.
169 | - Assigns values to variables in memory.
170 | - For functions, when invoked, JS creates a new function EC.
171 | - When a function returns a value, the function EC is destroyed.
172 |
173 | *Once the entire code execution is done, the Global EC will be destroyed as well.*
174 |
175 | ## Call Stack (Last In First Out)
176 |
177 | - To keep track of contexts, JS uses a call stack.
178 | - A call stack has a fixed size depending on the system or browser.
179 | - Exceeding the size limit causes a stack overflow error.
180 |
181 | We will explore more about scopes and how the JS engine works internally in later posts. So stay tuned โจ
182 |
183 |
184 | 
185 |
186 |
187 | # JavaScript Hoisting - Explained EASILY
188 |
189 | ## Prerequisite
190 | - JavaScript Execution Process
191 | - Basic knowledge of Scope
192 |
193 | Hoisting is a behavior in JavaScript where all declarations of a function, variable, or class go to the top of the scope they are defined in.
194 |
195 | This whole process is done during the Memory Creation Phase.
196 | Let's see what actually happens with:
197 |
198 | ### Variables
199 | - **`var`**: Variables are hoisted but with a default value of `undefined`.
200 | - **`let` and `const`**: Hoisted but inaccessible before default initialization. [Gives Error when accessed before initialization]
201 |
202 | ### Functions
203 | Functions become accessible even before the line they are declared. Hoisting does not occur in function expressions, it occurs only in function declarations.
204 |
205 | ### Point to Note
206 | - Hoisting happens based on the scope. It sets variables and functions to the top of the scope.
207 |
208 | ### Related Topic: Temporal Dead Zone
209 | - Area where variables are hoisted but inaccessible until they are initialized with a value. [Applies to `let` and `const`, not to `var`]
210 |
211 |
212 | ## From where I learned Hoisting?
213 | - Watch this video: [Akshay Saini's video](https://lnkd.in/gfdGax5P) ๐
214 | - Read this freeCodeCamp Article: [freeCodeCamp Article](https://lnkd.in/gyP6Qc_s)
215 |
216 |
217 | 
218 |
219 |
220 | # JavaScript: Function Declaration vs Function Expression and Much More๐ฅ
221 |
222 | ## Function Declaration (aka function statement) ๐
223 |
224 | - Named function where you declare a name after the `function` keyword.
225 |
226 | Example:
227 | ```javascript
228 | function myFunc() {
229 | // function body
230 | }
231 | ```
232 |
233 | ## Function Expression ๐
234 |
235 | - Anonymous functions, where we use the `function` keyword without a name, then assign it to a variable.
236 |
237 | Example:
238 | ```javascript
239 | const myFunc = function () {
240 | // function body
241 | };
242 | ```
243 |
244 | * Here you can use `var` or `let` as well.
245 | - If `var` is used, it will store `undefined` in the memory creation phase.
246 | - If `let` and `const` are used, it will throw an error: we cannot access them before initialization.
247 |
248 | ### Function Expression (Benefits and Drawbacks)
249 | - Cannot be accessed before initialization.
250 | - Needs to be assigned to be used later.
251 | - Anonymous functions are useful for anonymous operations, e.g., IIFEs, callback functions, etc.
252 |
253 | We can also have named function expressions like this:
254 |
255 | ```javascript
256 | const print = function x() {
257 | // function body
258 | };
259 | ```
260 | But here `x` is not accessible.
261 |
262 | ## Common Confusion: Parameters and Arguments
263 |
264 | - **Parameters**: In function definition.
265 | ```javascript
266 | function myFunc(param1, param2) {
267 | // function body
268 | }
269 | ```
270 |
271 | - **Arguments**: While calling functions.
272 | ```javascript
273 | let sum = add(arg1, arg2);
274 | ```
275 |
276 | ## First Class Functions / Citizens
277 |
278 | - Ability to use functions like values.
279 |
280 | In JavaScript, we can:
281 | - Assign a function to a variable.
282 | - Pass a function as an argument.
283 | - Return a function from another function.
284 |
285 | So, JavaScript functions are first class ๐ฅ
286 |
287 | # JavaScript: undefined vs Not defined๐ฅ
288 |
289 | ## Undefined
290 | - Predefined global variable that represents the value assigned to a variable during the memory creation phase.
291 |
292 | ## Not defined
293 | - Means the variable has not been declared at all. Accessing such a variable results in a reference error.
294 |
295 | ## Sum up ๐ช
296 | A variable that has been declared but not assigned a value is `undefined`, and a variable that has not been declared at all is `not defined`.
297 |
298 |
299 | 
300 |
301 |
302 | # JavaScript: Scope and Lexical Scope ๐ฅ
303 |
304 | ## Disclaimer โ
305 | This post is content-heavy.
306 |
307 | ## Scope
308 | - Area where an item (variable or function) is visible and accessible to other code.
309 |
310 | ## Lexical Scope (Static Scope)
311 | - A place where all the variables and functions of a parent lie. This scope is passed to the children scope (nested scope).
312 |
313 | Consider this code and call stack:
314 |
315 | ```javascript
316 | let name = "Tapesh";
317 | function a() {
318 | function b() {
319 | function c() {
320 | console.log(name);
321 | }
322 | c();
323 | }
324 | b();
325 | }
326 | a();
327 | ```
328 |
329 | ### Call Stack
330 | ```
331 | | C() |
332 | | B() |
333 | | A() |
334 | | GEC |
335 | |-----|
336 | ```
337 |
338 | ### Explanation
339 |
340 | - `C()` has access to variables and functions in its own scope + lexical scope of its parent (`B()`).
341 | - `B()` has access to its own scope + lexical scope of its parent (`A()`).
342 | - `A()` has access to its own scope + lexical scope of its parent (Global Execution Context).
343 | - Global Execution Context (GEC) has access to its own scope + parent (since it has no parent, it points to `null`).
344 |
345 | ## Scope Chain โ
346 |
347 | - Determines the hierarchy where JS code must go through to find the lexical scope (origin) of a specific variable.
348 |
349 | As in the above example:
350 | - Code first finds the `name` variable in `C`'s scope.
351 | - If not found, it goes to its lexical scope (that is `B`'s scope).
352 | - If not found, it goes to `A`'s scope.
353 | - If not found, it goes to GEC (found โ).
354 | - If not found, it returns a "not defined" error.
355 |
356 | ### Chain
357 | C -> B -> A -> GEC
358 |
359 |
360 | 
361 |
362 |
363 | # JavaScript: Types of Errors ๐คก
364 |
365 | Three types of errors you can see in JavaScript:
366 |
367 | ## Reference Errors
368 |
369 | When you attempt to use a variable (or a reference) that has not been declared.
370 |
371 | - Accessing undeclared variables.
372 | - Accessing a variable outside of its scope.
373 |
374 | ## Syntax Errors (no line executes in this case)
375 |
376 | When code does not conform to the structure or syntax rules of the JavaScript language.
377 |
378 | - Incorrect use of language constructs.
379 | - Missed or extra punctuations.
380 |
381 | ## Type Errors
382 |
383 | When an operation is performed on a value of an unexpected type.
384 |
385 | - Trying to call a function that is not a function.
386 | - Accessing properties or methods of `null` and `undefined`.
387 |
388 | ## Can You Answer This Question? ๐
389 |
390 | Which type of error will this snippet give?
391 |
392 | ```javascript
393 | function testFunction() {
394 | console.log(answer);
395 | }
396 |
397 | testFunction();
398 | ```
399 |
400 | 
401 |
402 |
403 | # JavaScript: Block Scope & Shadowing๐ฅ
404 |
405 | ## Topics Covered
406 | - Block
407 | - Block Scope
408 | - Shadowing
409 | - Illegal Shadowing
410 |
411 | ## What is a Block? (compound statement)
412 | A block is defined by curly braces `{...}`.
413 | - Used to combine multiple JavaScript statements into one group.
414 | - We can use it where JavaScript expects one single statement.
415 |
416 | **Example:**
417 | ```javascript
418 | if (true) {
419 | // block
420 | }
421 | ```
422 |
423 | ## Block Scoped
424 | - Scope in which we can access all variables and functions of that block. Lexical scope also works here.
425 |
426 | **Note:**
427 | - `let` and `const` are block scoped, meaning they cannot be accessed outside the block.
428 | - `var` is globally scoped.
429 |
430 | ## Shadowing
431 | - If we have the same named variable outside the block, then the block variable shadows the outside variable.
432 |
433 | **Example:**
434 | ```javascript
435 | let a = 1; // shadowed
436 | {
437 | let a = 2;
438 | console.log(a); // 2
439 | }
440 | ```
441 |
442 | Because `let` and `const` variables are stored in different memory locations: in the block object for block variables, and in the script object for global variables.
443 |
444 | **In short:**
445 | - Global: reserved for `var`
446 | - Script: for `let` and `const` (outside block)
447 | - Block: separate memory for variables (`let` and `const`) inside scope
448 |
449 | ## Illegal Shadowing
450 | - When an outside variable is declared with `let` or `const`, but inside the block, it is declared with `var`.
451 | - If a variable is shadowing any outside variable, it should not cross the boundary of its scope.
452 |
453 | **Example:**
454 | ```javascript
455 | let a = 10;
456 | {
457 | var a = 20; // illegal shadowing
458 | }
459 | ```
460 |
461 | However:
462 | ```javascript
463 | var a = 10;
464 | {
465 | let a = 20; // works fine since let creates a separate block
466 | }
467 | ```
468 |
469 | 
470 |
471 |
472 | # JavaScript: Closures ๐ฅ
473 |
474 | A closure is the combination of a function bundled together with a reference to its lexical environment.
475 |
476 | In JavaScript, a closure is a function that remembers its outer variables and can access them even when called independently.
477 |
478 | ## Advantages
479 | - Data handling / encapsulation
480 | - State retention
481 | - Currying (will study later)
482 | - Memoization
483 | - Asynchronous programming
484 | - Event handling
485 |
486 | ## Disadvantages
487 | - Variables declared inside a closure are not garbage collected.
488 | - Garbage collection is done when function execution gets completed. All the variables are deleted from memory.
489 | - Too many closures can slow down your application, caused by duplication of code in memory.
490 |
491 |
492 | 
493 |
494 |
495 | # JavaScript: Callback Functions ๐ฅ
496 |
497 | ## Callback Functions
498 |
499 | In JavaScript, callback functions are functions passed as arguments to another function, enabling asynchronous behavior.
500 |
501 | ### Need of Callback Functions
502 |
503 | - **Asynchronous JavaScript**: Callback functions aid in the development of asynchronous JavaScript code.
504 | - **Execution Control**: Ensures that a function does not execute until a specific task is completed, but rather runs immediately after task completion.
505 |
506 | ### Usage
507 |
508 | 1. **Event Handling**: Callback functions are commonly used for event handling.
509 | 2. **Web APIs**: Utilized with functions such as `setTimeout` or `setInterval`.
510 | 3. **Data Fetching**: In scenarios like fetching data from external sources.
511 |
512 | See the image below for visual representation:
513 |
514 |
515 | ### Tips
516 |
517 | - **Event Listener Optimization**: Removing event listeners when not in use can optimize memory usage, preventing potential slowdowns on websites.
518 |
519 |
520 | 
521 |
522 |
523 | # JavaScript: Working of Async Code ๐ฅ
524 |
525 | ## Prerequisite: Callback Function
526 |
527 | ### Blocking ๐ฅ
528 |
529 | - When tasks that take a lot of time (e.g., API calls, image processing) are executed in the main thread, they block the call stack or main thread until completion.
530 | - **Issue**: Blocking the main thread can lead to performance issues.
531 |
532 | **Solution**: Async Callbacks
533 |
534 | ### Process of Execution ๐ฅ
535 |
536 | 1. All callbacks are registered in the Web API with their attached timer and event.
537 | 2. Meanwhile, other code continues to execute.
538 | 3. When the timer expires or the callback is ready, it is pushed to the task queue but is not executed immediately.
539 |
540 | ### Event Loop ๐
541 |
542 | - The event loop checks if the call stack is empty.
543 | - If empty, it looks into the microtask queue and task queue for pending callbacks.
544 | - If a pending callback exists, the event loop pushes it to the top of the call stack for execution.
545 |
546 | ### Microtask Queue ๐ฅ
547 |
548 | - Introduced in ES6.
549 | - Used for promises and MutationObserver (changes in the DOM tree).
550 | - Has higher priority than the task queue.
551 | - The task queue must wait until the microtask queue is empty.
552 |
553 | ### Starvation of Task Queue ๐ด
554 |
555 | - Occurs when resolved promises keep adding to the microtask queue, preventing the task queue callbacks from executing.
556 | - This can delay task queue callbacks indefinitely.
557 |
558 | ### Note
559 |
560 | During Event Listener usage, the original callback remains in the Web API environment indefinitely because the event may occur again. Therefore, it is recommended to remove listeners when not in use to allow the garbage collector to free up memory.
561 |
562 | ### FAQs
563 |
564 | **Q. When does the Event Loop actually start?**
565 |
566 | **A.** The event loop is always running and doing its job.
567 |
568 | **Q. Are only async callbacks registered in the Web API?**
569 |
570 | **A.** Yes, only async code moves to the Web API.
571 |
572 | **Q. Does the Web API store only callback functions and push the same to the queue?**
573 |
574 | **A.** Yes, callback functions are stored and a reference is scheduled in queues.
575 |
576 | **Q. What if `setTimeout` delay is 0 ms?**
577 |
578 | **A.** Even with a 0 ms delay, the callback goes through the whole process and waits for the call stack to be empty.
579 |
580 |
581 | 
582 |
583 |
584 | # How JavaScript Engine Works ๐๐จ
585 |
586 | A browser has two main components:
587 | - **JavaScript Engine**
588 | - **Rendering Engine**
589 |
590 | ### JavaScript Engine
591 |
592 | The JavaScript Engine executes and compiles JavaScript into native machine code.
593 |
594 | - **Chrome**: v8 ๐ป
595 | - **Firefox**: SpiderMonkey ๐
596 | - **Safari**: JavaScriptCore ๐ฅ
597 | - **Edge (IE)**: Chakra โณ๏ธ
598 |
599 | ### Rendering Engine
600 |
601 | The Rendering Engine is responsible for rendering DOM trees, styles, events, etc. It paints the content on your screen.
602 |
603 | ### JS Engine Architecture
604 |
605 | - **Not a machine**: It's a program written in a low-level language.
606 | - **Function**: Takes high-level code (JavaScript) and converts it into machine-level code.
607 |
608 | #### Three MAIN steps to execute the code:
609 |
610 | 1. **Parsing**
611 | 2. **Compilation**
612 | 3. **Execution**
613 |
614 | ### 1. Parsing
615 |
616 | - **Process**: Reads code line by line.
617 | - **Steps**:
618 | 1. Breaks down code into tokens.
619 | 2. Passes tokens to a syntax parser.
620 |
621 | **Syntax Parser**: Converts the code into an AST (Abstract Syntax Tree).
622 |
623 | **AST**: Represents code as a tree-like structure.
624 |
625 | ### 2. Compilation
626 |
627 | JavaScript uses JIT (Just-In-Time) compilation, involving both an interpreter and a compiler.
628 |
629 | - **Process**:
630 | 1. AST goes to the interpreter (converted to high-level code).
631 | 2. Byte code then goes for execution.
632 |
633 | During step 1, the compiler helps optimize the code at runtime.
634 |
635 | ### 3. Execution
636 |
637 | Execution is not possible without the memory heap and call stack.
638 |
639 | - **Memory Heap**: Where all variables and functions are assigned to memory. It also includes a garbage collector to free up memory space whenever possible.
640 |
641 | **Garbage Collector**: Uses the mark-and-sweep algorithm to free up memory. ๐ฎ
642 |
643 | ### Note
644 |
645 | All browsers work differently, but the above steps are used by v8 and most engines work similarly.
646 |
647 |
648 | 
649 |
650 |
651 | # JavaScript: Callbacks Problems ๐ฅ
652 |
653 | ### Mainly two problems with callbacks:
654 |
655 | 1. **Callback Hell**
656 | 2. **Inversion of Control**
657 |
658 | ### 1. Callback Hell โ ๏ธ
659 |
660 | Callback hell occurs when multiple callbacks are nested within a function.
661 |
662 | - The shape of the code resembles a pyramid ("pyramid of doom").
663 | - This makes the code difficult to maintain and understand.
664 |
665 | ### 2. Inversion of Control ๐คธ๐ปโโ๏ธ
666 |
667 | Inversion of control means losing control over the code when using callbacks.
668 |
669 | - Control is given to another nested callback function, increasing dependency.
670 | - Essentially, we don't know what's happening behind the scenes.
671 |
672 | ### SOLUTION??
673 |
674 | **Promises** ๐ฅ
675 |
676 |
677 | 
678 |
679 |
680 | # JavaScript: Promises ๐ฅ
681 |
682 | A Promise is an assurance or guarantee that something will happen in the future.
683 |
684 | It can have two outcomes:
685 | - Fulfillment
686 | - Failure
687 |
688 | In JavaScript,
689 | a Promise is an object that will produce a single value after some time in the future.
690 |
691 | **Value:**
692 | - If successful: resolved value
693 | - If failed: reason
694 |
695 | Promises can have 3 possible states:
696 | - Pending: default state
697 | - Fulfilled: if successful
698 | - Rejected: if failed
699 |
700 | Promise transitions from:
701 | - pending -> fulfilled OR
702 | - pending -> rejected
703 |
704 | When using Promises, we have full control over the logic, allowing us to solve the inversion of control problem using promises.
705 |
706 | ### How to create promises?
707 |
708 | - Using `.then()` method:
709 | - It takes two callbacks:
710 | 1. If resolved
711 | 2. If rejected
712 | - `.then((value) => {}, (reason) => {})`
713 |
714 | - Always returns another promise, facilitating easy chaining.
715 | - Chaining helps solve the callback hell problem.
716 |
717 | ### How to handle errors in promises?
718 |
719 | - Using `.catch()` method:
720 | - If anything goes wrong in the promise, this method catches the reason for the error.
721 | - Using catch, errors no longer remain uncaught.
722 |
723 | ### `.finally()`
724 |
725 | - Method that always runs, regardless of whether resolved or rejected.
726 | - Here we can handle the result of promises whether rejected or resolved.
727 |
728 |
729 | 
730 |
731 |
732 | # JavaScript: Promise APIs ๐ฅ๐ฅ
733 |
734 | Promises in JavaScript are used to handle asynchronous operations. There are several Promise APIs that allow you to work with multiple promises efficiently.
735 |
736 | ## Promise APIs
737 |
738 | ### 1. `Promise.all()`
739 |
740 | - Used to run multiple promises in parallel.
741 | - Takes an iterable (array) of promises as an argument.
742 | - If all promises are fulfilled, returns an array of values after resolving.
743 | - If any promise is rejected, stops running and returns the error immediately.
744 | - Implements fail-fast behavior.
745 |
746 | ### 2. `Promise.allSettled()`
747 |
748 | - Introduced after ES2020.
749 | - Returns an array of all settled promises, whether fulfilled or failed.
750 | - Each array value is an object with properties:
751 | - `status`: Indicates whether the promise was fulfilled or rejected.
752 | - `value` or `reason`: Contains the resolved value or rejection reason, respectively.
753 |
754 | ### 3. `Promise.race()`
755 |
756 | - Returns a single promise as output.
757 | - Returns the promise that settles first (either fulfilled or rejected).
758 | - If the fastest promise is resolved, it stops there, and other promises are not executed.
759 | - If the fastest promise is rejected, it will not get any error if other promises failed or not because they will not get executed.
760 |
761 | ### 4. `Promise.any()`
762 |
763 | - Returns a single promise that resolves when any of the provided promises resolves.
764 | - If no promise is fulfilled, returns an *aggregate error*.
765 | - *Aggregate Error*: Represents several errors wrapped in a single error. It provides the reasons for rejection of all promises in an array.
766 |
767 | ## Conclusion
768 |
769 | These Promise APIs provide powerful tools for handling asynchronous operations and managing multiple promises effectively.
770 |
771 | Next Topic: Async/Await ๐ฅ
772 |
773 |
774 | 
775 |
776 |
777 | # JavaScript: Async/Await ๐ฅ
778 |
779 | Async/Await is syntactical sugar over `.then()` and `.catch()` chains, making promises handling more elegant.
780 |
781 | ## Async
782 |
783 | - Keyword to create an asynchronous function.
784 | - This function always returns a promise. If we don't explicitly return a promise, JavaScript automatically wraps the returned value in a promise.
785 |
786 | ## Await
787 |
788 | - Keyword that makes JavaScript wait until the promise is resolved or rejected.
789 | - Whenever the JavaScript engine encounters the `await` keyword, it suspends the complete function call from the call stack and continues with other work.
790 | - Once the promise is settled, the function comes back in the call stack and continues executing.
791 |
792 | `As time, tide, and JavaScript wait for none ๐`
793 |
794 | ### Why Async/Await?
795 |
796 | - No need for nested callbacks.
797 | - Simplified syntax.
798 | - No chaining required.
799 |
800 | ## Error Handling
801 |
802 | - Use `try/catch` for error handling with Async/Await.
803 |
804 | ```javascript
805 | try {
806 | // Try to resolve promise here
807 | } catch (error) {
808 | // Do work when an error occurs
809 | } finally {
810 | // Run regardless of whether the promise is resolved or rejected
811 | }
812 | ```
813 |
814 | 
815 |
816 |
817 | # JavaScript: `this` keyword ๐ฅ
818 |
819 | - `this` always refers to an object.
820 | - The object it refers to will vary depending on how and where `this` is being called.
821 | - It's not a variable, but a keyword (its value is not changed or reassigned).
822 |
823 | ## `this` in Global Scope
824 |
825 | - Refers to the global object:
826 | - `window` in the browser
827 | - `global` in Node.js
828 |
829 | ## `this` inside Functions
830 |
831 | - The value depends on strict/non-strict mode (will discuss in the next post):
832 | - In strict mode: `this` refers to `undefined`.
833 | - In non-strict mode: `this` refers to the global object. Why?
834 | - It also depends on how it is being called:
835 | - `function () {}`: `this` is `undefined`.
836 | - `window.function() {}`: `this` is `window` because it got a reference to the window.
837 |
838 | - This substitution:
839 | - If `this` is `undefined` or `null`, the `this` keyword will be replaced with the global object in non-strict mode.
840 |
841 | ## `this` inside an Object Method
842 |
843 | - Refers to the object.
844 |
845 | ## `this` inside Arrow Functions
846 |
847 | - Arrow functions do not have their own `this`.
848 | - They take `this` from their enclosing lexical environment.
849 |
850 | ## `this` inside DOM
851 |
852 | - Refers to the element where called:
853 | ```html
854 |
855 | ```
856 | - Prints the button element.
857 |
858 | ## `this` in call(), apply(), bind()
859 | - Will see later.
860 |
861 |
862 | 
863 |
864 |
865 | # JavaScript: "use strict" ๐ฅ
866 |
867 | "use strict" was introduced in ES5 and it makes JavaScript code execute in strict mode. It can be declared at the beginning of a script or a function.
868 |
869 | ## WHY?
870 |
871 | - **Easier to Write Secure JavaScript**: It helps catch common coding errors and unsafe actions, making code more robust.
872 | - **Throws Errors for Bad Syntax**: It throws errors for practices that are not considered good or safe.
873 |
874 | ## WHAT WE CAN'T DO?
875 |
876 | - Using variables/objects without declaring them using `var`, `let`, or `const`.
877 | - Deleting variables and function names.
878 | - Having duplicate parameters in a function.
879 | - Using octal numeric literals.
880 | - Writing to read-only properties.
881 | - Deleting undeletable properties.
882 | - Using certain keywords (`eval`, `arguments`, `private`, `public`, `static`, etc.) as variable names.
883 | - Declaring variables using the `eval` function.
884 | - This behaves differently inside functions.
885 |
886 | # JavaScript: call(), apply(), bind() ๐ฅ
887 |
888 | ## call()
889 |
890 | - **Purpose**: Change the context of the invoking function, allowing the replacement of the value of 'this' inside a function with any desired value.
891 | - **Syntax**: `func.call(newThisObj, arg1, arg2, ...)`
892 | - `newThisObj`: Value to replace 'this' inside the function. If not provided, the global object is considered.
893 | - `args`: Other required arguments for the function, if any.
894 |
895 | ## apply()
896 |
897 | - **Purpose**: Similar to `call()`, but arguments are passed as an array.
898 | - **Syntax**: `func.apply(newThisObj, [arg1, arg2, ...])`
899 |
900 | ## bind()
901 |
902 | - **Purpose**: Creates a copy of a function with a new value of 'this', which can be invoked later.
903 | - **Syntax**: `newFunc = func.bind(newThisObj, arg1, arg2, ...)`
904 | - `newFunc`: New function with the specified 'this' context.
905 | - `newThisObj`: Value to replace 'this' inside the function.
906 | - `args`: Other required arguments for the function.
907 |
908 |
909 | 
910 |
911 |
912 | # JavaScript: Currying ๐ ๐ฅ
913 |
914 | Transforms a function with multiple arguments into a nested series of functions, each taking a single argument.
915 |
916 | f(a, b, c) -> f(a)(b)(c) โ ๏ธ
917 |
918 | ## Why Currying?
919 |
920 | - helps avoid passing the same variable again and again
921 | - helps to create Higher Order Functions
922 | - fewer errors and side effects
923 |
924 | [enables checking method: checks if you have all the required things before you proceed]
925 |
926 | See the examples in the below image ๐ผ
927 |
928 | ## Currying vs Partial Application ๐ฅ
929 |
930 | - In currying, nested functions are equal to arguments, means each function must have a single argument.
931 |
932 | f(a, b, c) -> f(a)(b)(c)
933 |
934 | - Partial Application transforms a function into another function with smaller arguments (less args).
935 |
936 | f(a, b, c) -> f(a)(b, c)
937 |
938 | ## Currying using bind()
939 |
940 | - For currying, we can also use the bind function and separate the args in separate functions
941 | - because bind returns a new function.
942 |
943 | ```javascript
944 | curry = func.bind(this, arg1);
945 | curry(arg2);
946 | ```
947 | โ ๏ธ This topic needs a video reference to understand properly, so do YouTube โถ๏ธ to see more examples.
948 |
949 |
950 | 
951 |
952 |
953 | # JavaScript: Prototype ๐ฅ๐ฅ
954 |
955 | In JS, objects can inherit properties from another object.
956 |
957 | The object from where these properties are inherited is called Prototype.
958 |
959 | Example:
960 |
961 | All methods that are built-in within strings, arrays, and objects data structure.
962 |
963 | ---
964 |
965 | ## Prototype Chain โ๏ธ
966 |
967 | If we are accessing any property from a string/array/function, the property is not only searched in itself but also in the prototype. This chain continues until it reaches null.
968 |
969 | ### Visualization ๐
970 |
971 | string --prototype-> object --prototype-> null
972 |
973 | array --prototype-> object --prototype-> null
974 |
975 | function --prototype-> object --prototype-> null
976 |
977 | ๐ Every object in JavaScript has an internal private property [[๐ฉ๐ซ๐จ๐ญ๐จ๐ญ๐ฒ๐ฉ๐]]
978 |
979 | - not accessible directly in code
980 |
981 | But to find [[๐ฉ๐ซ๐จ๐ญ๐จ๐ญ๐ฒ๐ฉ๐]] we can use ๐๐ป
982 |
983 | ```javascript
984 | Object.getPrototypeOf(arr);
985 | // or
986 | arr.__proto__
987 | ```
988 |
989 |
990 | 
991 |
992 |
993 | ## Prototype Inheritance ๐ฅ
994 |
995 | The ability of JS objects to inherit properties from another object.
996 |
997 | Example: Array can access to all the properties of an object.
998 | Sure, here's the text converted directly into Markdown code:
999 |
1000 | # JavaScript: OOP Introduction๐ฅ
1001 |
1002 | JS is prototype based procedural language which means both functional and object oriented programming.
1003 |
1004 | ## โ Two ways to achieve OOP in JS
1005 |
1006 | - Constructor Function
1007 | - Class keyword (ES6, syntactic sugar over constructor function)
1008 |
1009 | See the image below to compare syntaxes ๐ผ
1010 |
1011 | We can create multiple instances of the same class using the `new` keyword.
1012 |
1013 | ```javascript
1014 | const obj = new SomeClass();
1015 | ```
1016 |
1017 | ## ๐ฃ๐ฟ๐ผ๐ฏ๐น๐ฒ๐บ ๐๐ถ๐๐ต ๐๐ผ๐ป๐๐๐ฟ๐๐ฐ๐๐ผ๐ฟ ๐ณ๐๐ป๐ฐ๐๐ถ๐ผ๐ป
1018 |
1019 | - Some common methods declared in the constructor function get duplicated in every instance, which is not memory efficient.
1020 |
1021 | So we need to put this common method in the prototype of the constructor function.
1022 |
1023 | Initially, `SomeClass.prototype` is an empty object.
1024 |
1025 | ```javascript
1026 | SomeClass.prototype.commonMethod = function () {}
1027 | ```
1028 |
1029 | ๐ Here we can't use arrow function, because we need `this` referring to the class to access other class variables and methods.
1030 |
1031 | In class keyword syntax, methods are automatically put inside the prototype.
1032 |
1033 |
1034 | 
1035 |
1036 | 
1037 |
1038 |
1039 | # JavaScript: Inheritance ๐ฅ๐จโ๐ฆ
1040 |
1041 | We can inherit properties and methods of a parent class in a child class.
1042 |
1043 | ## To inherit
1044 |
1045 | ### In Constructor Function
1046 |
1047 | - To get properties: call the Parent constructor function with Child `this`.
1048 | - To get methods: link the prototypes.
1049 |
1050 | **Syntax:**
1051 |
1052 | ```javascript
1053 | function Child(name) {
1054 | Parent.call(this, name); // Pass the required args
1055 | }
1056 | Child.prototype = Object.create(Parent.prototype);
1057 | ```
1058 |
1059 | - Make sure to write it above all child prototypes.
1060 |
1061 | ### Using Class Syntax
1062 |
1063 | - Use `extends` keyword.
1064 | - `super` keyword used to call the constructor of Parent.
1065 |
1066 | ```javascript
1067 | class Child extends Parent {
1068 | constructor(name) {
1069 | super(name); // Pass all the required args
1070 | }
1071 | }
1072 | ```
1073 |
1074 | # JavaScript: Abstraction and Encapsulation ๐ฅ
1075 |
1076 | ## Abstraction
1077 |
1078 | We can make properties and methods private so that no one outside the class can access these properties.
1079 |
1080 | Use `#` before property or method name to declare it as a private entity.
1081 |
1082 | ## Encapsulation
1083 |
1084 | The process of hiding and securing properties of objects. We need to provide another mechanism to access these private properties.
1085 |
1086 | Using Getters and Setters, since we can access private properties within the class.
1087 |
1088 | Look at the image below showcasing two different syntaxes ๐ผ
1089 |
1090 |
1091 | 
1092 |
1093 | 
1094 |
1095 |
1096 |
1097 | # JavaScript: Static Properties and Methods ๐ฅ
1098 |
1099 | These are shared by all instances of a class.
1100 |
1101 | ```javascript
1102 | class MyClass {
1103 | static count = 0;
1104 |
1105 | static getCount() {
1106 | return MyClass.count;
1107 | }
1108 | }
1109 | ```
1110 |
1111 | **Note:**
1112 |
1113 | - Can access static properties using class name or `this.constructor`.
1114 | - Cannot access from class instances.
1115 | - Static properties and methods are inherited.
1116 | - Static properties are initialized only once.
1117 |
1118 | ```javascript
1119 | const obj = new MyClass();
1120 | console.log(obj.count); // undefined
1121 |
1122 | console.log(MyClass.count); // 0
1123 | ```
1124 |
1125 | ## Static Block
1126 |
1127 | - We can create a static block which will run the first time a static method is used.
1128 |
1129 | ```javascript
1130 | static {
1131 | // ...
1132 | }
1133 | ```
1134 |
1135 | 
1136 |
1137 |
1138 | # JavaScript: Event Bubbling & Capturing ๐ฅ
1139 |
1140 | Propagation refers to how an event travels through the DOM.
1141 |
1142 | ## โ Phases of Propagation
1143 |
1144 | - **Bubbling**
1145 | - **Capturing**
1146 |
1147 | For simplicity, we are using the click event to understand.
1148 |
1149 | ### Bubbling ๐ฏ -> ๐ฑ
1150 |
1151 | - Propagation of an event from the target (clicked element) to the root (highest level parent of the target).
1152 |
1153 | If the target is a child:
1154 | 1. First, the child is clicked.
1155 | 2. Second, the parent is clicked.
1156 | 3. Third, the grandparent is clicked.
1157 | - And so on, until the root element where the last event occurs.
1158 |
1159 | ### Capturing (Trickling) ๐ฑ -> ๐ฏ
1160 |
1161 | - Propagation of an event from the root to the target.
1162 |
1163 | If the target is a child:
1164 | 1. First, the grandparent is clicked.
1165 | 2. Second, the parent is clicked.
1166 | 3. Third, the child is clicked.
1167 |
1168 | We can trigger bubbling/capturing and control over the propagation.
1169 |
1170 | ```javascript
1171 | ele.addEventListener(event, callback, useCapture);
1172 | ```
1173 |
1174 | - **useCapture**: optional boolean value.
1175 | - Default: `false` (bubbling)
1176 | - `true` (capturing)
1177 |
1178 | ## Problem:
1179 | These propagations take time and increase workload.
1180 |
1181 | ### Solution?
1182 |
1183 | ```javascript
1184 | e.stopPropagation();
1185 | ```
1186 |
1187 | - Prevents further propagation.
1188 | - Stops all the parent event listeners but not other handlers on the target ๐ฏ.
1189 |
1190 | ```javascript
1191 | e.stopImmediatePropagation();
1192 | ```
1193 |
1194 | - Stops all the parent event listeners and other event listeners on the target as well.
1195 |
1196 | 
1197 |
1198 |
1199 | # JavaScript: Event Delegation ๐ฅ
1200 |
1201 | Event delegation is a technique in JavaScript where we delegate the responsibility of handling an event to a parent element.
1202 |
1203 | By doing so:
1204 |
1205 | - โ๏ธ We avoid attaching multiple event listeners to individual child elements.
1206 | - โ๏ธ Performance improvement.
1207 | - โ๏ธ Dynamic (adding new elements will automatically have event listeners).
1208 | - โ๏ธ Code simplification.
1209 |
1210 |
1211 | 
1212 |
1213 |
1214 | # JavaScript: Script Loading ๐ฅ
1215 |
1216 | Three ways to load scripts:
1217 |
1218 | 1. `