6 |
7 | ## Index
8 |
9 | ### Beginner
10 |
11 | - let vs var vs const
12 | - Difference between function declaration & function expression
13 | - Primitive data type
14 | - Coercion
15 | - Passing by Value vs. Reference
16 | - Timer function
17 | - Truthy and Falsy values
18 |
19 | ### Advanced
20 |
21 | - Spread operator
22 | - Rest syntax
23 | - Destructuring
24 | - Higher-Order function
25 | - Closures
26 | - call() , apply() and bind()
27 | - hoisting : hoist a flash i.e move it to the top
28 | - Currying function
29 | - Event Bubbling and Capturing
30 | - Debugging
31 | - Generator Function
32 |
33 |
34 |
35 | - Local storage vs Session storage
36 | - Asynchronous js
37 | - JavaScript Design Patterns
38 | - Iterators and generators
39 | - throttle vs debounce
40 | - object creation patterns tutorial - factory , constructor pattern, prototype pattern
41 | - JavaScript ES2020
42 | - Tricky JavaScript interview questions and answers
43 |
44 |
45 | ### CSS Notes
46 |
47 | https://github.com/ResourceAggregator/Frontend-stuff/blob/master/css/css.md
48 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-cayman
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # Index
2 |
3 | ### Beginner
4 |
5 | - let vs var vs const
6 | - Function
7 |
8 | A. Parameters vs arguments
9 |
10 | B. Difference between function declaration & function expression
11 |
12 | C. Arrow function
13 |
14 | - Primitive data type
15 | - Coercion
16 | - Passing by Value vs. Reference
17 | - Timer function
18 | - Difference between Attribute and Property
19 | - Cookies
20 | - Difference between innerHTML and innerText
21 | - Truthy and Falsy values
22 | - DOM Manipulation
23 | - Error and error handling
24 | - Infinities
25 |
26 |
27 | ### Good to know
28 |
29 | - Execution context
30 | - Execution Stack
31 | - JavaScript Prototypes
32 |
33 | ### Advanced
34 |
35 | - Spread operator
36 | - Rest syntax
37 | - Destructuring
38 | - Higher-Order function
39 | - Closures
40 | - call() , apply() and bind()
41 | - hoisting : hoist a flash ie move it to the top
42 | - Currying function
43 | - Event Bubbling and Capturing
44 | - Debugging
45 | - Local storage vs Session storage
46 |
47 |
48 | - Asynchronous js
49 | - JavaScript Design Patterns
50 | - Iterators and generators
51 | - throttle vs debounce
52 | - object creation patterns tutorial - factory , constructor pattern, prototype pattern
53 | - JavaScript ES2020
54 | - Tricky JavaScript interview questions and answers
55 |
56 |
57 |
58 |
59 | # Begineer
60 |
61 |
62 | 
63 |
64 | ## 1. let vs var vs const
65 |
66 | - `const` means that the identifier can't be reassigned. But the value can be changed using var and let
67 | - let has a block scope while var has function scope. const also has a block scope
68 | - var has been in js from the beginning and let was introduced recently
69 | 
70 |
71 | `let : l : block and better`
72 |
73 | - var gets hoisted at the top, but variables defined with let doesn't get hoisted
74 |
75 | **Example of var:**
76 |
77 | ```
78 | Input:
79 | console.log(x);
80 | let x=5;
81 | console.log(x);
82 |
83 | Output:
84 | Error
85 | ```
86 |
87 | **Example of let**:
88 |
89 | ```
90 | Input:
91 | console.log(x);
92 | let x=5;
93 | console.log(x);
94 |
95 | Output:
96 | Error
97 | ```
98 |
99 | In the example below, we get an error because 'let' baz in the second case, has only block scope
100 |
101 | ```
102 | function run() {
103 | var foo = "Foo";
104 | let bar = "Bar";
105 | console.log(foo, bar);
106 | {
107 | let baz = "Bazz";
108 | console.log(baz);
109 | }
110 | console.log(baz); // ReferenceError
111 | }
112 |
113 | run();
114 | ```
115 |
116 | 
117 |
118 |
119 |
120 | ## 2. Functions
121 |
122 | #### A. Parameters vs arguments
123 |
124 | ```
125 | function hi(a,b) // a and b are parameters
126 | {
127 | console.log(“hi “,a,b)
128 | }
129 |
130 | Hi(“Riya”,”James”) // Riya and James are arguments
131 |
132 | ```
133 |
134 | #### B. Difference between function declaration & function expression
135 |
136 | - Function declaration:
137 |
138 | `function doStuff() {};`
139 |
140 | - Function expression:
141 |
142 | `const doStuff = function() {} `
143 |
144 | - Function declarations are hoisted but function expressions are not.
145 |
146 | **Example: Function Expression**
147 |
148 | `alert(foo()); // ERROR! foo wasn't loaded yet`
149 |
150 | `var foo = function() { return 5; } `
151 |
152 | **Example: Function Declaration**
153 |
154 | ` alert(foo()); // Alerts 5. Declarations are loaded before any code can run.`
155 |
156 | `function foo() { return 5; }`
157 |
158 |
159 |
160 | #### C. Arrow function
161 |
162 | All arrow functions should be anonymous
163 |
164 | ```
165 | CONVERTION
166 |
167 | const hi = function (a,b)
168 | {
169 | console.log(“hi “,a,b)
170 | }
171 |
172 | Remove ‘function’ and add => btw parameter and the brackets
173 |
174 | const hi=(a,b)=>{…}
175 |
176 | ```
177 |
178 | 
179 |
180 | ## 3. Primitive data type
181 |
182 | Following is the list of primitive data types in javascript.
183 |
184 | 1. Boolean
185 | 2. Null
186 | 3. Undefined
187 | 4. Number
188 | 5. BigInt
189 | 6. String
190 | 7. Symbol
191 |
192 | ```
193 | typeof NaN // “number”
194 |
195 | typeof Infinity // “number”
196 |
197 |
198 |
199 | let a;
200 | console.log(a) //undefined
201 |
202 | - Undefined is used when we declare a variable but haven’t assigned a value to it
203 | - We use null to explicitly tell that there is nothing
204 | Eg: let a=null
205 |
206 | ```
207 |
208 | 
209 |
210 |
211 |
212 | ## 4. Coercion
213 |
214 | When doing mathematical operations, JavaScript can convert numbers to strings:
215 |
216 | - usually adds two numbers. If it is a string, it concatenates them.
217 |
218 | * always subtracts. So if a string is given, it is converted to number.
219 | So 2- 'abc' , the output is NaN
220 |
221 | 
222 |
223 | 'a' -'b' the output is NaN and typeof NaN is number
224 |
225 | 
226 | **Example**
227 |
228 | ```
229 | var x = 5 + 7; // x.valueOf() is 12, typeof x is a number
230 |
231 | var x = 5 + "7"; // x.valueOf() is 57, typeof x is a string
232 |
233 | var x = "5" + 7; // x.valueOf() is 57, typeof x is a string
234 |
235 | var x = 5–7; // x.valueOf() is -2, typeof x is a number
236 |
237 | var x = 5 - "7"; // x.valueOf() is -2, typeof x is a number
238 |
239 | var x = "5" - 7; // x.valueOf() is -2, typeof x is a number
240 |
241 | var x = 5 - "x"; // x.valueOf() is NaN, typeof x is a number
242 | ```
243 |
244 | - Subtracting a string from a string, does not generate an error but returns NaN (Not a Number):
245 |
246 | ```
247 | Example
248 | "Hello" - "Dolly" // returns NaN
249 | ```
250 |
251 | Example
252 |
253 | ```
254 | var x = "John";
255 | var y = new String("John");
256 | (x === y) // is false because x is a string and y is an object
257 | ```
258 |
259 | **Example**
260 |
261 | ```
262 | Boolean('') // false
263 | Boolean(0) // false
264 | Boolean(-0) // false
265 | Boolean(NaN) // false
266 | Boolean(null) // false
267 | Boolean(undefined) // false
268 | Boolean(false) // false
269 |
270 | Boolean({}) // true
271 | Boolean([]) // true
272 | Boolean(Symbol()) // true
273 | !!Symbol() // true
274 | Boolean(function() {}) // true
275 | Number(null) // 0
276 | Number(undefined) // NaN
277 | Number(true) // 1
278 | Number(false) // 0
279 | Number(" 12 ") // 12
280 | Number("-12.34") // -12.34
281 | Number("\n") // 0
282 | Number(" 12s ") // NaN
283 | Number(123) // 123
284 | ```
285 |
286 | ###### References
287 |
288 | 1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness
289 | 2. https://medium.com/javascript-in-plain-english/how-type-coercion-in-javascript-works-be723e411c0b
290 | 3. https://www.freecodecamp.org/news/js-type-coercion-explained-27ba3d9a2839/
291 |
292 | Type Conversions in JavaScript tutorial
293 |
294 | 1. https://www.youtube.com/watch?v=j9xuvChJftg&list=PL7pEw9n3GkoW5bYOhVAtmJlak3ZK7SaDf&index=53
295 |
296 | 
297 |
298 |
299 |
300 | ## 5. Passing by Value vs. Reference
301 |
302 | 
303 |
304 | - When assigning a variable (a) a primitive value the equals operator sets up a location (address) in memory (represented by 0x001 in the picture) to store the information and points the variable (a) to that address.
305 |
306 | 
307 |
308 | - Passing by reference relates to objects in Javascript (ALL objects including functions).
309 |
310 | In some programming languages, you can actually decide whether something is passed by value or reference, with your code syntax. But in JavaScript you don't have that option. All primitive types are by value, and all objects are by reference.
311 |
312 | _Reference_
313 |
314 | https://codeburst.io/javascript-passing-by-value-vs-reference-explained-in-plain-english-8d00fd06a47c
315 |
316 |
317 |
318 | ## 6. Timer function
319 |
320 | There are two methods for it:
321 |
322 | - setTimeout allows us to run a function once after the interval of time.
323 | - setInterval allows us to run a function repeatedly, starting after the interval of time, then repeating continuously at that interval.
324 |
325 |
326 |
327 |
328 | 
329 |
330 | 
331 |
332 |
333 |
334 |
335 | ## 7. Cookies
336 |
337 | Cookies are the most efficient method of remembering and tracking preferences, purchases, commissions, and other information required for better visitor experience or site statistics.
338 |
339 | Cookies are a plain text data record of 5 variable-length fields −
340 |
341 | ### Expires −
342 | The date the cookie will expire. If this is blank, the cookie will expire when the visitor quits the browser.
343 |
344 | ### Domain −
345 | The domain name of your site.
346 |
347 | ### Path −
348 | The path to the directory or web page that set the cookie. This may be blank if you want to retrieve the cookie from any directory or page.
349 |
350 | ### Secure −
351 | If this field contains the word "secure", then the cookie may only be retrieved with a secure server. If this field is blank, no such restriction exists.
352 |
353 | ### Name=Value −
354 | Cookies are set and retrieved in the form of key-value pairs
355 |
356 |
357 |
358 | ## Functions on Cookies
359 |
360 | ### Create a Cookie -
361 | document.cookie = "username=Annu; expires=Thu, 1 Oct 2020 10:00:00 UTC";
362 | ### Read a Cookie -
363 | var x = document.cookie;
364 | ### Change a Cookie -
365 | You can change a cookie the same way as you create it:
366 | document.cookie = "username=John Smith; expires=Thu, 1 Oct 2020 10:00:00 UTC; path=/";
367 | ### Delete a Cookie -
368 | document.cookie = "username=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
369 |
370 |
371 |
372 |
373 |
374 |
375 | ## 8. Difference between Attribute and Property
376 | - Attributes provide additional information about the HTML elements, attributes are always specified in the start tag and they usually come in name/value pairs.
377 | - Properties are the values associated with a JavaScript object, these objects are collection of unordered properties and these properties can be usually be changed, added, and deleted.
378 | - Properties are accessed from DOM (Document Object Model) nodes.
379 |
380 | While writing HTML code, we can define attributes on our HTML elements. Then, once the browser parses our code, a corresponding DOM(Document Object Model) node will be created. This node is an object, and therefore it has properties.
381 |
382 | **Example**
383 | ```
384 |
385 | ```
386 | The id property is a reflected property for the id attribute.Getting the property reads the attribute value, and setting the property writes the attribute value.
387 |
388 | ## 9. Difference between innerHTML and innerText
389 |
390 | The innerHTML tag returns the text including all spacing and inner element tags.
391 | On the other hand, innerText property returns just the text, without spacing and inner element tags.
392 |
393 | In simple words, innerText retrieves and sets the content of the tag as plain text, whereas innerHTML retrieves and sets the content in HTML format.
394 |
395 | **Example**
396 |
397 | If HTML has the following tag,
398 |
399 | ```
400 |
This element has extra spacing and contains a span element.
401 | ```
402 |
403 | and the JavaScript has the following code,
404 |
405 | ```
406 | var iText = document.getElementById("example").innerText
407 | var iHtml = document.getElementById("example").innerHTML
408 | ```
409 |
410 | The value stored in `iText` would be `This element has extra spacing and contains a span element.` and `iHTML` would have `This element has extra spacing and contains a span element.`.
411 |
412 | ## 10. Truthy and Falsy values
413 |
414 | In JavaScript, a truthy value is a value that is considered true when encountered in a Boolean context. All values are truthy unless they are defined as falsy.
415 |
416 | JavaScript uses type coercion in Boolean contexts.
417 |
418 | Some examples of truthy values in JavaScript: (which will be coerced to true in boolean contexts, and thus execute the if block)
419 |
420 | ```
421 | if (true)
422 | if ({})
423 | if ([])
424 | if (42)
425 | if ("0")
426 | if ("false")
427 | if (new Date())
428 | if (-42)
429 | if (12n)
430 | if (3.14)
431 | if (-3.14)
432 | if (Infinity)
433 | if (-Infinity)
434 | ```
435 |
436 | 
437 |
438 | A falsy (sometimes written falsey) value is a value that is considered false when encountered in a Boolean context.
439 |
440 | JavaScript uses type conversion to coerce any value to a Boolean in contexts that require it, such as conditionals and loops.
441 |
442 | There are 8 falsy values:
443 |
444 | ```
445 | false The keyword false
446 | 0 The number zero
447 | -0 The number negative zero
448 | 0n BigInt, when used as a boolean, follows the same rule as a Number. 0n is falsy.
449 | "" Empty string value
450 | null null - the absence of any value
451 | undefined undefined - the primitive value
452 | NaN NaN - not a number
453 | ```
454 |
455 | 
456 |
457 |
458 |
459 |
460 | ## 11.DOM Manipulation
461 |
462 | Document Object Model, or DOM for short, represents all page content as objects that can be modified. And Javascript allow us to modify DOM.
463 |
464 | The main 2 objects provided by the DOM API that you will interact the most with are document and window.
465 |
466 | 1. The Window object - The window object represents the window that contains the DOM document.
467 | window.document points to the document object loaded in the window.
468 | Properties and methods of this object can be called without referencing window explicitly, because it represents the global object. So, the previous property window.document is usually called just document.
469 |
470 | - Properties - Here is a list of useful Window properties you will likely reference a lot:
471 | >- **console** points to the browser debugging console. Useful to print error messages or logging, using console.log, console.error and other tools (see the Browser DevTools article)
472 | >- **document** as already said, points to the document object, key to the DOM interactions you will perform
473 | >- **history** gives access to the History API
474 | >- **location** gives access to the Location interface, from which you can determine the URL, the protocol, the hash and other useful information.
475 | >- **localStorage** is a reference to the Web Storage API localStorage object
476 | >- **sessionStorage** is a reference to the Web Storage API sessionStorage object
477 |
478 | - Methods - Here is a list of useful Window Methods you will likely reference a lot:
479 | >- alert(): which you can use to display alert dialogs
480 | >- postMessage(): used by the Channel Messaging API
481 | >- requestAnimationFrame(): used to perform animations in a way that’s both performant and easy on the CPU
482 | >- setInterval(): call a function every n milliseconds, until the interval is cleared with clearInterval()
483 | >- clearInterval(): clears an interval created with setInterval()
484 | >- setTimeout(): execute a function after ‘n’ milliseconds
485 | >- setImmediate(): execute a function as soon as the browser is ready
486 | >- addEventListener(): add an event listener to the document
487 | >- removeEventListener(): remove an event listener from the document
488 |
489 | 2. Document - The Document interface represents any web page loaded in the browser and serves as an entry point into the web page's content, which is the DOM tree.
490 |
491 | Note:-
492 | - Window is the main JavaScript object root, also known as the global object in a browser, also can be treated as the root of the document object model. You can access it as window.
493 | - Document is the main object of the potentially visible/rendered document object model/DOM.
494 |
495 |
496 | Example of a DOM tree:-
497 |
498 | Representation of a portion of the DOM pointing to the head and body tags:
499 | 
500 |
501 | Tags are element nodes (or just elements) and form the tree structure: is at the root, then and are its children, etc.
502 |
503 | #### **1. Traversing the DOM**
504 | All operations on the DOM start with the document object. That’s the main “entry point” to DOM. From it we can access any node.
505 | > 
506 |
507 | #### **2. Getting the parent**
508 | You can you can use **Node.parentNode** or **Node.parentElement** (where Node means a node in the DOM).
509 | > 
510 |
511 | #### **3. Getting the children**
512 | - To access all the Children Element Nodes of a node, use **Node.childNodes**.
513 | > 
514 |
515 | - To get the first child Element Node, use **Node.firstElementChild**. To get the last child Element Node, use **Node.lastElementChild**:
516 | > 
517 |
518 | - **Node.firstChild** - It is a read-only property returns the node's first child in the tree, or null if the node has no children. If the node is a Document, it returns the first node in the list of its direct children.
519 |
520 | - **Node.lastChild** - It is a read-only property returns the last child of the node. If its parent is an element, then the child is generally an element node, a text node, or a comment node. It returns null if there are no child elements.
521 | > 
522 |
523 | #### **4. Modifying the DOM**
524 | The DOM offers various methods to edit the nodes of the page and alter the document tree with:-
525 | - **document.createElement()**: creates a new Element Node
526 | - **document.createTextNode()**: creates a new Text Node
527 | you can create new elements, and add them to the DOM elements you want as children, by using document.appendChild():
528 | ```
529 | const div = document.createElement('div')
530 | div.appendChild(document.createTextNode('Hello world!'))
531 | ```
532 | - **first.removeChild(second)** removes the child node “second” from the node “first”.
533 | - **document.insertBefore(newNode, existingNode)** inserts “newNode” as a sibling of “existingNode”, placing it before that in the DOM tree structure.
534 | - **element.appendChild(newChild)** alters the tree under “element”, adding a new child Node “newChild” to it, after all the other children.
535 | - **element.prepend(newChild)** alters the tree under “element”, adding a new child Node “newChild” to it, before other child elements. You can pass one or more child Nodes, or even a string which will be interpreted as a Text node.
536 | - **element.replaceChild(newChild, existingChild)** alters the tree under “element”, replacing “existingChild” with a new Node “newChild”.
537 | - **element.insertAdjacentElement(position, newElement)** inserts “newElement” in the DOM, positioned relatively to “element” depending on “position” parameter value. See the possible values.
538 | - **element.textContent = 'something'** changes the content of a Text node to “something”.
539 |
540 | **Reference**
541 |
542 | ## 12. Infinities
543 |
544 | #### * Positive INFINITY
545 |
546 | POSITIVE_INFINITY is displayed when a number exceeds the upper limit of the floating point numbers, which is "1.797693134862315E+308"
547 |
548 | alert(Math.pow(10, 1000)); /* Infinity */
549 |
550 | #### * Negative INFINITY
551 |
552 | NEGATIVE_INFINITY is displayed when a number exceeds the lower limit of the floating point numbers, which is "-1.797693134862316E+308".
553 |
554 | **POSITIVE_INFINITY** vs. **MAX_VALUE** (or **NEGATIVE_INFINITY** vs. **MIN_VALUE** )
555 | 1. The value of the MAX_VALUE property is the largest number your JavaScript interpreter can handle. Larger value will be viewed as POSITIVE_INFINITY.
556 | 2. The value of NEGATIVE_INFINITY and POSITIVE_INFINITY are read-only they cannot be changed by
557 | your scripts; they are returned by JavaScript whenever a function or operation returns a number
558 | larger than the MAX_VALUE the JavaScript interpreter can handle
559 | **See the code snippet**
560 |
561 | 
562 | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
563 |
564 |
565 | - https://javascript.info/
566 | - https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model
567 |
568 |
569 |
570 | ## 12. Errors
571 |
572 | 
573 |
574 | ""To err is human..." Everyone makes a mistake, even the seasoned developer. Hence, it's essential to know about different errors and how to solve them. Errors can be divided into two groups: compile-time errors and run-time errors.
575 |
576 | #### A. Compile-time errors
577 |
578 | Compile-time errors are a class of errors which prevents the program from compiling:
579 |
580 | - syntax error: incorrect keyword, a forgotten symbol
581 | - calling a non-existing method
582 | - wrong source code file name
583 |
584 | In the case of JavaScript, compile-time errors occur at interpret time. For example, in the below code, a syntax error occurs because it is missing left Parentheses '(' in the print function/method invocation.
585 |
586 | ```
587 |
592 | ```
593 | To avoid such errors, developers use a modern Integrated Development Environment with a code analyzer.
594 |
595 | #### B. Run-time errors
596 |
597 | Run-time errors (also known as "exceptions") are errors when the program is running. Run-time errors will cause your program to behave unexpectedly or may even stop the execution.
598 |
599 | There are two subtypes of run-time errors:
600 |
601 | - logic errors – program produces a wrong result because of incorrect code.
602 | For example, for addition writing statement as "sum = x - y;"
603 | - unhandled exceptional events like division by zero
604 |
605 | To avoid such errors, developers must learn debugging skills, write automated tests, and implement code reviews.
606 |
607 | ## 13. Error Handling
608 |
609 | 
610 |
611 |
612 | When your program has a "broken" line of code, your program dies, and after stopping program execution, an error message is printed on the console.
613 |
614 | But can we add some immunity to our program so that rather than dying, it can handle the error?
615 |
616 | Yes, we can! "try..catch" statement lets us handle the error and do something useful. For example, rather than crashing when a number is divided by zero, we can print a message that the divider can't be zero.
617 |
618 | ```
619 | try {
620 |
621 | // code where exception can exist
622 |
623 | } catch (err) {
624 |
625 | // steps that should be taken to handle exception
626 |
627 | }
628 | ```
629 |
630 |
631 |
632 |
633 |
634 | # Good to know
635 |
636 | ## 1. Execution context
637 |
638 | When a JavaScript engine executes a script, it creates execution contexts. Execution context (EC) is defined as the environment in which the JavaScript code is executed. By environment, I mean the value of this, variables, objects, and functions JavaScript code has access to at a particular time.
639 |
640 | ```
641 | Execution Context (Global), created by JS Engine contains 3 important things for you:
642 |
643 | - Global object - window
644 | - Special Object this
645 | - Ref to outer environment
646 | ```
647 |
648 | **Each execution context has two phases: the creation phase and the execution phase.**
649 |
650 | A. Creation PHASE
651 |
652 | - Creation phase is the phase in which the JS engine has called a function but its execution has not started. In the creation phase, JS engine is in the compilation phase and it just scans over the function code to compile the code, it doesn’t execute any code.
653 |
654 | - As the parser runs through your code and begins to set up what you've written for translation, it recognizes where you've created variables and where you've created functions. And so it sets up in this creation phase, the memory space for the variables and functions. And it's that step that is somewhat confusingly called hoisting.
655 |
656 | - All this means is that before your code begins to be executed line by line, the JavaScript engine has already set aside memory space for the variables that you've created in that entire code that you've built, and all of the functions that you've created as well. So those functions and those variables exist in memory. So when the code begins to execute line by line, it can access them.
657 |
658 | - However, when it comes to variables, it's a little bit different. You see the function in its entirety is placed into memory space, meaning that the function, its name and the code inside the function is being executed. However the next phase, the execution phase is where it actually executes your code line by line, that's when these kind of assignments are set, where var a = 1. So the JavaScript engine when it sets up the memory space for a, it doesn't know what its value will ultimately end up being until it starts executing its code. So instead, it puts a placeholder called undefined. That placeholder means oh, I don't know what this value is yet.
659 |
660 | - All variables in JavaScript are initially set to undefined, and functions are sitting in memory in their entirety.
661 |
662 | B. Execution PHASE
663 |
664 | When the code is executed line-by-line (by JS interpreeter) it can access the variables defined inside Execution Context
665 | variable assignment are done in this phase
666 |
667 |
668 |
669 | ## 2. Execution Stack
670 |
671 | When the JavaScript engine first encounters your script, it creates a global execution context and pushes it to the current execution stack. Whenever the engine finds a function invocation, it creates a new execution context for that function and pushes it to the top of the stack.
672 |
673 | The engine executes the function whose execution context is at the top of the stack. When this function completes, its execution stack is popped off from the stack, and the control reaches to the context below it in the current stack.
674 |
675 | 
676 |
677 | ## 3. JavaScript Prototypes
678 |
679 | Every JavaScript object has an internal hidden "slot" called [[Prototype]]. You can think of a slot as a property on an object, internal to the JavaScript engine, hidden from the code you write
680 |
681 | **Prototype chain**
682 | The prototype chain mechanism is simple: When you access a property p on object obj, the JavaScript engine will search this property inside obj object. If the engine fails to search, it continues searching in the prototype of obj object and so on until reaching Object.prototype. If after the search has finished, and nothing has been found the result will be undefined
683 |
684 | Modern JavaScript implementations allow read and/or write access to the [[Prototype]] in the following ways:
685 |
686 | - The new operator (configures the prototype chain on the default object returned from a constructor function),
687 | - The extends keyword (configures the prototype chain when using the class syntax),
688 | - Object.create will set the supplied argument as the [[Prototype]] of the resulting object,
689 | - Object.getPrototypeOf and Object.setPrototypeOf (get/set the [[Prototype]] after object creation), and
690 | - The standardized accessor (ie. getter/setter) property named **proto** (similar to 4.)
691 |
692 | ** “The **proto** is simply a reference to the prototype object from which the instance has inherited”.**
693 |
694 | In a language implementing classical inheritance like Java, C# or C++ you start by creating a class--a blueprint for your objects--and then you can create new objects from that class or you can extend the class, defining a new class that augments the original class.
695 |
696 | In JavaScript you first create an object (there is no concept of class), then you can augment your own object or create new objects
697 |
698 | **Prototype Property: Prototype-based Inheritance**
699 | Prototype is important in JavaScript because JavaScript does not have classical inheritance based on Classes (as most object oriented languages do), and therefore all inheritance in JavaScript is made possible through the prototype property. JavaScript has a prototype-based inheritance mechanism.Inheritance is a programming paradigm where objects (or Classes in some languages) can inherit properties and methods from other objects (or Classes). In JavaScript, you implement inheritance with the prototype property. For example, you can create a Fruit function (an object, since all functions in JavaScript are objects) and add properties and methods on the Fruit prototype property, and all instances of the Fruit function will inherit all the Fruit’s properties and methods.
700 |
701 | https://javascript.info/prototype-inheritance
702 |
703 |
704 |
705 |
706 |
707 | # Advanced
708 |
709 | ## 1. Spread operator
710 |
711 | spread syntax refers to the use of an ellipsis of three dots ( … ) to expand an iterable object into the list of arguments
712 |
713 | ```
714 | const foo = ['hello', 'bonjour', 'konnichiwa'];
715 | const bar = [...foo];
716 | console.log(bar);
717 | // ['hello', 'bonjour', 'konnichiwa']
718 | ```
719 |
720 | _Difference between spread and assignment operator_
721 |
722 | ```
723 | const foo = ['hello', 'bonjour', 'konnichiwa'];
724 | const bar1 = [...foo];
725 | const bar2 = foo;
726 | bar1.push('a');
727 | bar2.push('b');
728 | console.log(foo); //["hello", "bonjour", "konnichiwa", "b"]
729 | console.log(bar1); // ["hello", "bonjour", "konnichiwa", "a"]
730 | console.log(bar2); // ["hello", "bonjour", "konnichiwa", "b"]
731 | ```
732 |
733 | Arrays and objects are mutable while strings and int are immutable. So, when we write bar2 = foo, we are using call by reference. Hence, when we edited bar2.push('b'); the value of foo also changed
734 | But using spread operator, we are creating two instances
735 |
736 | ```
737 | // destrucing in objects
738 | const foo = {
739 | english: 'hello',
740 | french: 'bonjour',
741 | japanese: 'konnichiwa'
742 | };
743 | const bar = {...foo};
744 | console.log(bar);
745 | // { english: 'hello', french: 'bonjour', japanese: 'konnichiwa' }
746 | ```
747 |
748 |
749 |
750 | ## 2. Rest syntax
751 |
752 | The rest syntax can also be used to pick up property keys that are not already picked up by the destructuring pattern. Those keys and their values are copied into a new object:
753 |
754 | ```
755 | let person = {name: "Sarah", country: "Nigeria", job: "Developer" friends: ["Annie", "Becky"]};
756 | let person = {name: "Sarah", country: "Nigeria", job: "Developer" friends: ["Annie", "Becky"]};
757 | let {name, friends, ...others} = person;
758 | console.log(name);//"Sarah"
759 | console.log(friends);//["Annie", "Becky"]
760 | console.log(others);// {country: "Nigeria", job: "Developer"}
761 | ```
762 |
763 |
764 |
765 | ## 3. Destructuring
766 |
767 | The destructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables.
768 |
769 | 1. **Arrays** : We can write any name for the parameter(greeting, prononu) and order is important
770 |
771 | ```
772 | let introduction = ["Hello", "I" , "am", "Sarah"];
773 | let [greeting, pronoun] = introduction;
774 | console.log(greeting);//"Hello"
775 | console.log(pronoun);//"I"
776 | ```
777 |
778 | 2. **Objects**: Here the parameter name should be equal to the key of the object and order is not important
779 |
780 | ```
781 | //USUAL MANNER
782 | let person = {name: "Sarah", country: "Nigeria", job: "Developer"};
783 | let name = person.name;
784 | let country = person.country;
785 | let job = person.job;
786 | console.log(name);//"Sarah"
787 | console.log(country);//"Nigeria"
788 | console.log(job);//Developer"
789 |
790 |
791 | // DESTRUCTURING
792 | let {name, country, job} = person;
793 | console.log(name);//"Sarah"
794 | console.log(country);//"Nigeria"
795 | console.log(job);//Developer"
796 | ```
797 |
798 |
799 |
800 | ## 4. Higher-Order function
801 |
802 | A Higher-Order function is a function that receives a function as an argument or returns the function as output.
803 |
804 | 
805 |
806 | **a. Map function**
807 |
808 | The map() method creates a new array with the results of calling a function for every array element.
809 | The map() method calls the provided function once for each element in an array, in order. It does not change the original array.
810 |
811 | ```
812 | const arr1 = [1, 2, 3];
813 | const arr2 = arr1.map(item => item * 2);
814 | console.log(arr2);
815 | ```
816 |
817 | **b. Filter**
818 |
819 | ```
820 | const persons = [
821 | { name: 'Peter', age: 16 },
822 | { name: 'Mark', age: 18 },
823 | { name: 'John', age: 27 },
824 | { name: 'Jane', age: 14 },
825 | { name: 'Tony', age: 24},
826 | ];const fullAge = persons.filter(person => person.age >= 18);console.log(fullAge);
827 | ```
828 |
829 |
830 |
831 | ## 5. Closures
832 |
833 | A closure is a function having access to the parent scope, even after the parent function has closed.
834 |
835 | A Basic Example of Closures in JavaScript:
836 |
837 | ```
838 | function outerFunc() {
839 | let outerVar = 'I am outside!';
840 |
841 | function innerFunc() {
842 | console.log(outerVar); // => logs "I am outside!"
843 | }
844 |
845 | return innerFunc;
846 | }
847 |
848 | const myInnerFunc = outerFunc();
849 | myInnerFunc();
850 | ```
851 |
852 | Closure means that an inner function always has access to the vars and parameters of its outer function, even after the outer function has returned.
853 | 
854 | 
855 |
856 | Refer : https://dmitripavlutin.com/simple-explanation-of-javascript-closures/
857 |
858 |
859 | ## 6. call() , apply() and bind()
860 |
861 | They all attach this into function (or object) and the difference is in the function invocation (see below).
862 |
863 | - call attaches this into function and executes the function immediately:
864 |
865 | ```
866 | var person = {
867 | name: "James Smith",
868 | hello: function(thing) {
869 | console.log(this.name + " says hello " + thing);
870 | }
871 | }
872 | person.hello("world"); // output: "James Smith says hello world"
873 | person.hello.call({ name: "Jim Smith" }, "world"); // output: "Jim Smith says hello world"
874 | ```
875 |
876 | - bind attaches this into function and it needs to be invoked separately like this:
877 |
878 | ```
879 | var person = {
880 | name: "James Smith",
881 | hello: function(thing) {
882 | console.log(this.name + " says hello " + thing);
883 | }
884 | }
885 |
886 | person.hello("world"); // output: "James Smith says hello world"
887 |
888 | var helloFunc = person.hello.bind({ name: "Jim Smith" });
889 |
890 | helloFunc("world"); // output: Jim Smith says hello world"
891 | ```
892 |
893 | or like this:
894 |
895 | ```
896 | var helloFunc = person.hello.bind({ name: "Jim Smith" }, "world");
897 | helloFunc(); // output: Jim Smith says hello world"
898 | ```
899 |
900 | - apply is similar to call except that it takes an array-like object instead of listing the arguments out one at a time:
901 |
902 | ```
903 | function personContainer() {
904 |
905 | var person = {
906 | name: "James Smith",
907 | hello: function() {
908 | console.log(this.name + " says hello " + arguments[1]);
909 | }
910 | }
911 | person.hello.apply(person, arguments);
912 | }
913 |
914 | personContainer("world", "mars"); // output: "James Smith says hello mars", note: arguments[
915 |
916 | ```
917 |
918 |
919 | 1. You can use call()/apply() to invoke the function immediately. bind() returns a bound function that, when executed later, will have the correct context ("this") for calling the original function. So bind() can be used when the function needs to be called later in certain events when it's useful.
920 |
921 | 2. Note that when using the apply() function the parameter must be placed in an array. Call() accepts both an array of parameters and a parameter itself.
922 |
923 | ```
924 | const greetingJohn = greeting.bind(john, 'uk');
925 | greetingJohn();//must be called again
926 | greeting.call(person,'India');
927 | greeting.apply(person,['India']);// has an array
928 | ```
929 |
930 | **Refernce**
931 |
932 | https://medium.com/r?url=https%3A%2F%2Fcodesquery.com%2Fjavascript-call-apply-bind-method%2F
933 |
934 |
935 |
936 | ## 7. Hoisting : hoist a flash ie move it to the top
937 |
938 | Hoisting is JavaScript's default behavior of moving declarations to the top.In JavaScript, a variable can be declared after it has been used.In other words; a variable can be used before it has been declared
939 |
940 |
941 |
942 | ## 8. Currying function
943 |
944 | - Currying is a transformation of functions that translates a function from callable as f(a, b, c) into callable as f(a)(b)(c).
945 |
946 | Currying is when you break down a function that takes multiple arguments into a series of functions that each take only one argument. Here's an example in JavaScript:
947 |
948 | ```
949 | function add (a, b) {
950 | return a + b;
951 | }
952 | add(3, 4); // returns 7
953 | ```
954 |
955 | This is a function that takes two arguments, a and b, and returns their sum. We will now curry this function:
956 |
957 | ```
958 | function add (a) {
959 | return function (b) {
960 | return a + b;
961 | }
962 | }
963 | ```
964 |
965 | This is a function that takes one argument, a, and returns a function that takes another argument, b, and that function returns their sum.
966 |
967 | ```
968 | add(3)(4);
969 | var add3 = add(3);
970 | add3(4);
971 | ```
972 |
973 | The first statement returns 7, like the add(3, 4) statement. The second statement defines a new function called add3 that will add 3 to its argument. This is what some people may call a closure. The third statement uses the add3 operation to add 3 to 4, again producing 7 as a result.
974 |
975 |
976 |
977 | ## 9. Event Bubbling and Capturing
978 |
979 | Event bubbling and capturing are two ways of event propagation in the HTML DOM API, when an event occurs in an element inside another element, and both elements have registered a handle for that event.
980 |
981 | 
982 |
983 | With bubbling, the event is first captured and handled by the innermost element and then propagated to outer elements.
984 | With capturing, the event is first captured by the outermost element and propagated to the inner elements.
985 |
986 |
987 |
988 | ## 10. Debugging
989 |
990 | https://www.youtube.com/watch?v=-bS6u_oQFtc&list=PL7pEw9n3GkoW5bYOhVAtmJlak3ZK7SaDf&index=29
991 |
992 | ## 11. Generator function
993 |
994 | Function keyword followed by an asterisk is used to define a generator function, which returns a Generator object.
995 | We can exit and re-entered the generator function later on. In case of re-entrances, their context (variable bindings) will be saved.
996 | Important point to note here is that calling a generator function does not execute its body immediately, in fact it returns an iterator object for the function.
997 | In short, a generator appears to be a function but it behaves like an iterator.
998 |
999 | * Generators are a special class of functions that simplify the task of writing iterators.
1000 | * A generator is a function that produces a sequence of results instead of a single value, i.e you generate a series of values.
1001 |
1002 | ```
1003 | Syntax :
1004 |
1005 | function* generatorFunctionName([param[, param[, ... param]]]) {
1006 | statements
1007 | }
1008 | ```
1009 | ```
1010 | name : Function name
1011 | param | Optional : Formal parameter for the function.
1012 | statements : Comprising the body of the function.
1013 | ```
1014 | ```
1015 | function* generator(i) {
1016 | yield i;
1017 | yield i + 1;
1018 | }
1019 | const gen = generator(1);
1020 | console.log(gen.next().value);
1021 | // expected output: 1
1022 | console.log(gen.next().value);
1023 | // expected output: 2
1024 | ```
1025 |
1026 |
1027 |
1028 | ## 12. Asynchronous js
1029 |
1030 | 1. Callback function
1031 | 2. Promises
1032 | 3. Async await
1033 |
1034 | JavaScript is synchronous by default and is single threaded. This means that code cannot create new threads and run in parallel. JavaScript introduced several features that help us with asynchronous code that do not involve using callbacks:
1035 |
1036 | **Reference**
1037 |
1038 | - https://flaviocopes.com/javascript-promises/
1039 | - https://flaviocopes.com/javascript-async-await/
1040 | - https://www.youtube.com/watch?v=IGoAdn-e5II
1041 |
1042 | ## 13. JavaScript Design Patterns
1043 |
1044 | https://medium.com/better-programming/javascript-design-patterns-25f0faaaa15
1045 |
1046 |
1047 | ## 14. Iterators and generators
1048 |
1049 | Iterators are a new way to loop over any collection in JavaScript.
1050 |
1051 | https://codeburst.io/a-simple-guide-to-es6-iterators-in-javascript-with-examples-189d052c3d8e
1052 |
1053 |
1054 |
1055 | ## 15. Throttle vs debounce
1056 |
1057 | Throttling and debouncing are two ways to optimize event handling.
1058 |
1059 | 
1060 |
1061 | - Debouncing enforces that a function not be called again until a certain amount of time has passed without it being called. As in "execute this function only if 100 milliseconds have passed without it being called."
1062 |
1063 | - Throttling enforces a maximum number of times a function can be called over time. As in "execute this function at most once every 100 milliseconds."
1064 |
1065 | _Good demo (codepen)_
1066 | https://css-tricks.com/the-difference-between-throttling-and-debouncing/
1067 |
1068 |
1069 |
1070 | ## 16. Object creation patterns tutorial
1071 |
1072 | https://www.youtube.com/watch?v=xizFJHKHdHw&list=PL7pEw9n3GkoW5bYOhVAtmJlak3ZK7SaDf&index=5
1073 |
1074 | JavaScript has a multitude of styles for creating objects
1075 |
1076 | #### 1. Object Literals
1077 |
1078 | ```
1079 | var o = {
1080 | x: 42,
1081 | y: 3.14,
1082 | f: function() {},
1083 | g: function() {}
1084 | };
1085 | ```
1086 |
1087 | #### 2. Factory Functions
1088 |
1089 | This is the absolute simplest way to create a family of objects that share the same structure, interface, and implementation. Rather than creating an object literal directly, instead we return an object literal from a function. This way, if we need to create the same type of object multiple times or in multiple places, we only need to invoke a function:
1090 |
1091 | ```
1092 | function thing() {
1093 | return {
1094 | x: 42,
1095 | y: 3.14,
1096 | f: function() {},
1097 | g: function() {}
1098 | };
1099 | }
1100 | var o = thing();
1101 | ```
1102 |
1103 | **Reference**
1104 |
1105 | - https://www.sitepoint.com/javascript-object-creation-patterns-best-practises/
1106 | - https://www.javascripttutorial.net/create-objects-in-javascript/
1107 |
1108 | - https://medium.com/r?url=https%3A%2F%2Fwww.dofactory.com%2Fjavascript%2Fdesign-patterns
1109 | - https://www.dofactory.com/javascript/design-patterns
1110 |
1111 |
1112 |
1113 | ## 17. JavaScript ES2020
1114 |
1115 | The new JavaScript features in ES2020 are:
1116 |
1117 | ➡️ String.prototype.matchAll
1118 |
1119 | ➡️ import()
1120 |
1121 | ➡️ BigInt
1122 |
1123 | ➡️ Promise.allSettled
1124 |
1125 | ➡️ globalThis
1126 |
1127 | ➡️ for-in mechanics
1128 |
1129 | ➡️ Optional Chaining
1130 |
1131 | ➡️ Nullish coalescing Operator
1132 |
1133 | _Reference_
1134 |
1135 | - https://radiant-brushlands-42789.herokuapp.com/medium.com/better-programming/javascript-es2020-features-with-simple-examples-d301dbef2c37
1136 | - https://www.freecodecamp.org/news/javascript-new-features-es2020/
1137 |
1138 |
1139 |
1140 | ## 18. Local storage vs Session storage
1141 |
1142 | localStorage and sessionStorage accomplish the exact same thing and have the same API, but with sessionStorage the data is persisted only until the window or tab is closed, while with localStorage the data is persisted until the user manually clears the browser cache or until your web app clears the data. The examples in this post are for localStorage, but the same syntax works for sessionStorage.
1143 |
1144 | ```
1145 | Create key/value pair entries with localStorage.setItem, providing a key and a value:
1146 | let key = 'Item 1';
1147 | localStorage.setItem(key, 'Value');
1148 | ```
1149 |
1150 | **Reference**
1151 |
1152 | - https://www.digitalocean.com/community/tutorials/js-introduction-localstorage-sessionstorage
1153 |
1154 |
1155 |
1156 | ## 19. Iterators
1157 |
1158 |
1159 | Iterators are a new way to loop over any collection in JavaScript.
1160 | An iterable is an object that can return an iterator using the iter() function; while an iterator is an object that keeps state and produces the next value when you call the next() function on it.
1161 |
1162 | Following values are iterables:
1163 | - Arrays
1164 | - Strings
1165 | - Maps
1166 | - Sets
1167 | - DOM data structures (work in progress)https://github.com/TroyTae/game-of-life/blob/master/README.md
1168 |
1169 | Plain objects are not iterable!
1170 |
1171 | Iterators are Objects which uses iterator protocols.
1172 | - After defining iterator next() method is used to iterate over the collection.
1173 |
1174 | ```
1175 | let numbers = new Sequence(1,2,3,4,5,6);
1176 | let iterator = numbers[Symbol.iterator]();
1177 |
1178 | let result = iterator.next();
1179 |
1180 | while(!result.done) {
1181 | console.log(result.value);
1182 | result=iterator.next()
1183 | }
1184 | ```
1185 |
1186 | What is the difference between loops and iterators?
1187 | There are two types of for loops which behave very differently.
1188 | - One uses indices.
1189 | ```
1190 | let arr = [1,2,3,4]
1191 | for(let index = 0; i< arr.length; i++){
1192 | console.log(arr[index])
1193 | }
1194 | ```
1195 |
1196 | - This kind of loop isn't always possible. For example, Lists have indices, but Sets don't, because they're unordered collections. The other one, the foreach loop uses an Iterator behind the scenes:.
1197 |
1198 | ```
1199 | let mySet = new Set();
1200 | mySet.add(1);
1201 | mySet.add(2);
1202 | mySet.add(3);
1203 | mySet.add(4);
1204 | for (let item of mySet) {
1205 | console.log(item)
1206 | }
1207 | ```
1208 | And finally, you can use an Iterator, which also works with any Iterable:
1209 | The iterator provides advantage in cases
1210 | + Where you want to move over the collection in both forward and backward using next() and previous() function.
1211 | + When you want to remove elements from collections safely while iterating over collections.
1212 | When you want to do more than just iterating over collection Iterator can be used.
1213 | + You can loop through the list using a for loop as many times as you want, but you can only loop through the list using an iterator once. To loop again using an iterator you will need to reinitialize the iterator.
1214 |
1215 | We have to initialize the iterator over the collection before using it.
1216 | ```
1217 | //Wrong
1218 | let arr = [1,2,3,4,5,6];
1219 | arr.next();
1220 |
1221 | //Correct
1222 | let arr = [1,2,3,4,5,6]
1223 | let iterator = arr[Symbol.iterator]();
1224 |
1225 | iterator.next();
1226 |
1227 | ```
1228 | **References**
1229 | - https://codeburst.io/a-simple-guide-to-es6-iterators-in-javascript-with-examples-189d052c3d8e
1230 | - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators
1231 | - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols
1232 |
1233 |