├── 01 Intro to JS ├── 01 Intro to JS │ ├── Code │ │ ├── consolelog.js │ │ ├── hello.js │ │ ├── operators.js │ │ ├── typeof.js │ │ └── variable.js │ └── Notes │ │ └── intro-to-js-notes.md ├── 02 Intro to JS-2 │ ├── Codes │ │ ├── breakDemo.js │ │ ├── conditionals.js │ │ ├── continueDemo.js │ │ ├── forLoop.js │ │ ├── functions.js │ │ ├── operators2.js │ │ ├── switch.js │ │ ├── unaryOperator.js │ │ └── whileLoop.js │ └── Notes │ │ └── intro-to-js-notes-2.md └── 03 Coercion │ ├── Codes │ ├── toNumber_demo.js │ ├── toNumber_demo2.js │ └── toString_demo.js │ └── Notes │ ├── Coercion.md │ ├── Coercion2.md │ └── Coercion3.md ├── 02 Advance JS ├── 05 ToBoolean & Strict Equality │ ├── Codes │ │ ├── Strict_equality.js │ │ └── ToBoolean.js │ └── Notes │ │ └── ToBoolean_strict_operator.md ├── 06 Abstract equality, NaN, Special Types │ ├── Codes │ │ ├── Number.isNaN_demo.js │ │ ├── abstract_equality_demo.js │ │ ├── isNaN_demo.js │ │ └── truthy_falsy_demo.js │ └── Notes │ │ └── Abstract_operator_NaN.md ├── 07 Scopes │ ├── Codes │ │ ├── blockScope_demo.js │ │ ├── const_demo.js │ │ ├── functionScope_demo.js │ │ ├── globalScope_demo.js │ │ ├── let_demo.js │ │ ├── lexicalScope1.js │ │ ├── lexicalScope2.js │ │ ├── lexicalScope3.js │ │ └── var_demo.js │ └── Notes │ │ └── Scope.md ├── 08 Scopes 2 │ ├── Codes │ │ ├── autoGlobal.js │ │ ├── autoglobal2.js │ │ ├── autoglobal3.js │ │ ├── example.js │ │ ├── hoisting.js │ │ ├── strict_mode.js │ │ ├── undeclared.js │ │ └── undefined.js │ └── Notes │ │ └── scopes2.md ├── 09 Function Expression │ ├── Codes │ │ ├── anonymous_function.js │ │ ├── functionExpression.js │ │ ├── passingFunction.js │ │ └── scope_of_fn_expression.js │ └── Notes │ │ └── function_expression.md ├── 10 Closures and Intro to Callbacks │ ├── Codes │ │ ├── array_map_function.js │ │ ├── callback_demo.js │ │ ├── setInterval2.js │ │ ├── setInterval_demo.js │ │ └── setTimeout_demo.js │ └── Notes │ │ └── closure.md ├── 11 Promises and callbacks │ ├── Codes │ │ ├── closure_demo.js │ │ ├── closure_demo2.js │ │ ├── closure_demo3.js │ │ ├── closure_demo4.js │ │ └── closure_demo5.js │ └── Notes │ │ └── closures2-promise.md └── 12 Async Nature of JS │ └── Codes │ ├── demo.js │ ├── demo2.js │ ├── demo3.js │ └── whyIsThisHappening.js ├── 03 Async JS ├── 13 Promises │ └── Codes │ │ ├── callback_hell.js │ │ ├── callback_inversion_of_control.js │ │ ├── download_callback.js │ │ ├── promise_demo1.js │ │ ├── promise_demo2.js │ │ └── promise_demo3.js └── 14 Promises Continued │ └── Codes │ └── feature.js └── README.md /01 Intro to JS/01 Intro to JS/Code/consolelog.js: -------------------------------------------------------------------------------- 1 | //boolean 2 | console.log(true); 3 | console.log(false); 4 | 5 | //number 6 | console.log(0); 7 | console.log(-0); 8 | 9 | //string 10 | console.log("JS basics - Arvind Pandit"); 11 | console.log("Arvind"); 12 | console.log(`arvind pandit`); 13 | 14 | //null and undefined 15 | console.log(null); 16 | console.log(undefined); 17 | -------------------------------------------------------------------------------- /01 Intro to JS/01 Intro to JS/Code/hello.js: -------------------------------------------------------------------------------- 1 | console.log("Hello world"); 2 | -------------------------------------------------------------------------------- /01 Intro to JS/01 Intro to JS/Code/operators.js: -------------------------------------------------------------------------------- 1 | //arithmetic operators 2 | console.log(2 + 5); 3 | console.log(5 / 2); //2.5 4 | console.log(Math.floor(5 / 2)); //2 5 | console.log(5 % 2); //remainder ie 1 6 | 7 | //assigment operators 8 | let x = 2; 9 | x += 2; 10 | console.log(x); //4 11 | x /= 2; 12 | console.log(x); //2 13 | x %= 2; 14 | console.log(x); //0 15 | 16 | //logical operators 17 | console.log(3 < 5 && 9 < 3); 18 | console.log(4 || 0); //4 19 | console.log(4 && 0); //0 20 | console.log(0 || 4); //4 21 | console.log(0 && 4); //0 22 | -------------------------------------------------------------------------------- /01 Intro to JS/01 Intro to JS/Code/typeof.js: -------------------------------------------------------------------------------- 1 | console.log(typeof 2); //number 2 | 3 | console.log(typeof "arvind"); // string 4 | 5 | console.log(typeof undefined); //undefined 6 | 7 | console.log(typeof null); //object !!!!!!!!!!!! why??????? 8 | 9 | console.log(typeof NaN); //number 10 | 11 | //interesting question 12 | console.log(typeof typeof 10); 13 | -------------------------------------------------------------------------------- /01 Intro to JS/01 Intro to JS/Code/variable.js: -------------------------------------------------------------------------------- 1 | //initializing a variable 2 | 3 | let firstName = "arvind"; 4 | const age = 21; 5 | var mathsMarks = 97; 6 | 7 | console.log(firstName, age, mathsMarks); 8 | -------------------------------------------------------------------------------- /01 Intro to JS/01 Intro to JS/Notes/intro-to-js-notes.md: -------------------------------------------------------------------------------- 1 | # Introduction to JavaScript 2 | 3 | JavaScript (JS) is a multipurpose programming language that can be used in various domains such as frontend and backend web development, machine learning algorithms, desktop applications, mobile apps, and scripting. It is a high-level, interpreted language known for its versatility and widespread use. 4 | 5 | ## Multi-Paradigm Language 6 | 7 | JavaScript is a multi-paradigm language, which means it supports multiple programming paradigms, including: 8 | 9 | - **Procedural Programming**: Writing code as a sequence of steps or procedures. 10 | - **Object-Oriented Programming (OOP)**: Organizing code into objects that encapsulate data and behavior. 11 | - **Functional Programming**: Treating functions as first-class citizens, allowing for a more declarative programming style. 12 | 13 | JavaScript's multi-paradigm nature allows developers to choose the most suitable approach for solving a particular problem, making it a flexible and adaptable language. 14 | 15 | ## Basic Values in JavaScript 16 | 17 | JavaScript has several basic types of values, including: 18 | 19 | - **Null**: Represents the intentional absence of any object value. 20 | - **Undefined**: Indicates the absence of a defined value. 21 | - **Boolean**: Represents the logical values of true or false. 22 | - **String**: Represents a sequence of characters enclosed in single quotes ('') or double quotes (""). 23 | - **Number**: Represents numeric values, including integers and floating-point numbers. 24 | - **Symbol**: Represents a unique identifier and is typically used for creating object properties. 25 | - **Object**: Represents a collection of key-value pairs or properties. 26 | 27 | Here are some examples of using these basic values in JavaScript: 28 | 29 | ```javascript 30 | // Boolean 31 | console.log(true); 32 | console.log(false); 33 | 34 | // Number 35 | console.log(0); 36 | console.log(-0); 37 | 38 | // String 39 | console.log("JS basics - Arvind Pandit"); 40 | console.log("Arvind"); 41 | console.log(`arvind pandit`); 42 | 43 | // Null and Undefined 44 | console.log(null); 45 | console.log(undefined); 46 | ``` 47 | 48 | ## typeof Operator 49 | 50 | The `typeof` operator is used to determine the type of a value or expression in JavaScript. It returns a string indicating the type. 51 | 52 | ```javascript 53 | console.log(typeof 2); // "number" 54 | console.log(typeof "arvind"); // "string" 55 | console.log(typeof undefined); // "undefined" 56 | console.log(typeof null); // "object" (!) This is a historical quirk in JavaScript. 57 | console.log(typeof NaN); // "number" 58 | 59 | // Interesting question 60 | console.log(typeof typeof 10); // "string" 61 | ``` 62 | 63 | ## Programs and Processes 64 | 65 | In JavaScript, a program refers to the code contained in a file, while a process represents the program in its running state or phase. When a program is executed, it requires memory allocation, and variables come into the picture as a mechanism to store values during the process. 66 | 67 | ## Variables 68 | 69 | Variables in JavaScript act as buckets in memory that store values. We give a label to these buckets, which is the variable name, to access them. 70 | 71 | Here's how to initialize variables in JavaScript: 72 | 73 | ```javascript 74 | let firstName = "arvind"; 75 | const age = 21; 76 | var mathsMarks = 97; 77 | 78 | console.log(firstName, age, mathsMarks); 79 | ``` 80 | 81 | ## Operators 82 | 83 | Operators in JavaScript are tools used to perform operations on values and obtain desired results. Here are a few types of operators commonly used in JavaScript: 84 | 85 | ### Arithmetic Operators 86 | 87 | Arithmetic operators perform mathematical calculations on numeric values. 88 | 89 | ```javascript 90 | console.log(2 + 5); // 7 91 | console.log(5 / 2); // 2.5 92 | console.log(Math.floor(5 / 2)); // 2 93 | console.log(5 % 2); // 1 (remainder) 94 | ``` 95 | 96 | ### Assignment Operators 97 | 98 | Assignment operators are used to assign values to variables and modify their values. 99 | 100 | ```javascript 101 | let x = 2; 102 | x += 2; 103 | console.log(x); // 4 104 | x /= 2; 105 | console.log(x); // 2 106 | x %= 2; 107 | console.log(x); // 0 108 | ``` 109 | 110 | ### Logical Operators 111 | 112 | Logical operators are used to combine and manipulate Boolean values. 113 | 114 | ```javascript 115 | console.log(3 < 5 && 9 < 3); // false 116 | console.log(4 || 0); // 4 117 | console.log(4 && 0); // 0 118 | console.log(0 || 4); // 4 119 | console.log(0 && 4); // 0 120 | ``` 121 | 122 | ## Conclusion 123 | 124 | In this introduction to JavaScript, we covered the basics of the language. JavaScript is a versatile programming language used in various domains. We discussed its multi-paradigm nature, basic values, variables, and operators. This is just the start, and we'll be covering more fundamental concepts in JavaScript. Stay tuned for further exploration! 125 | -------------------------------------------------------------------------------- /01 Intro to JS/02 Intro to JS-2/Codes/breakDemo.js: -------------------------------------------------------------------------------- 1 | for (let i = 0; i <= 10; i++) { 2 | if (i == 5) { 3 | console.log("breaking out the nearest loop"); 4 | break; 5 | } else console.log(i); 6 | } 7 | -------------------------------------------------------------------------------- /01 Intro to JS/02 Intro to JS-2/Codes/conditionals.js: -------------------------------------------------------------------------------- 1 | let x = 10; 2 | 3 | if (x >= 10) { 4 | console.log("Greater than or equal to 10"); 5 | } else { 6 | console.log("Less than 10"); 7 | } 8 | 9 | // if - else if - else if - else 10 | -------------------------------------------------------------------------------- /01 Intro to JS/02 Intro to JS-2/Codes/continueDemo.js: -------------------------------------------------------------------------------- 1 | let text = ""; 2 | 3 | for (let i = 0; i < 10; i++) { 4 | if (i <= 3) { 5 | continue; 6 | } 7 | text = text + i; 8 | } 9 | 10 | console.log(text); 11 | -------------------------------------------------------------------------------- /01 Intro to JS/02 Intro to JS-2/Codes/forLoop.js: -------------------------------------------------------------------------------- 1 | for (let i = 0; i <= 10; i++) { 2 | console.log(i); 3 | } 4 | -------------------------------------------------------------------------------- /01 Intro to JS/02 Intro to JS-2/Codes/functions.js: -------------------------------------------------------------------------------- 1 | function sum(a, b) { 2 | return a + b; 3 | } 4 | 5 | console.log(sum(10)); //Nan 6 | console.log(sum()); //NaN 7 | 8 | let x = sum(10, 50); 9 | console.log(x); 10 | 11 | //return keyword return an output and immediately stops the execution of the program; 12 | 13 | console.log(console.log(10)); //prints 10 and the undefined 14 | -------------------------------------------------------------------------------- /01 Intro to JS/02 Intro to JS-2/Codes/operators2.js: -------------------------------------------------------------------------------- 1 | // string based operator 2 | // + concatenate two or more strings 3 | 4 | console.log("Arvind " + "Pandit"); 5 | console.log("Js basics " + 2); 6 | 7 | //bitwise operators 8 | console.log(5 & 1); //logical and 9 | console.log(5 | 1); // logical or 10 | //left shift << 11 | //right shift >> 12 | //xor ^ 13 | // not ~ 14 | 15 | //ternary operator 16 | 2 < 1 ? console.log("Arvind") : console.log("Pandit"); 17 | -------------------------------------------------------------------------------- /01 Intro to JS/02 Intro to JS-2/Codes/switch.js: -------------------------------------------------------------------------------- 1 | let day = "wednesday"; 2 | 3 | switch (day) { 4 | case "monday": 5 | console.log("monday"); 6 | break; 7 | case "tuesday": 8 | console.log("tuesday"); 9 | break; 10 | case "sunday": 11 | console.log("sunday"); 12 | break; 13 | default: 14 | console.log("not valid day"); 15 | } 16 | -------------------------------------------------------------------------------- /01 Intro to JS/02 Intro to JS-2/Codes/unaryOperator.js: -------------------------------------------------------------------------------- 1 | let x = 10; 2 | 3 | y = x++; 4 | console.log(y); //10 5 | console.log(x); //11 6 | 7 | let m = 100; 8 | c = m--; 9 | 10 | console.log(c); //100 11 | console.log(m); //99 12 | -------------------------------------------------------------------------------- /01 Intro to JS/02 Intro to JS-2/Codes/whileLoop.js: -------------------------------------------------------------------------------- 1 | let x = 0; 2 | 3 | while (x <= 10) { 4 | console.log(x); 5 | x++; 6 | } 7 | -------------------------------------------------------------------------------- /01 Intro to JS/02 Intro to JS-2/Notes/intro-to-js-notes-2.md: -------------------------------------------------------------------------------- 1 | # Introduction to JavaScript - Part 2 2 | 3 | In this document, we will continue our exploration of JavaScript by discussing various operators and control flow statements. We will cover comparison operators, string-based operators, bitwise operators, the ternary operator, conditionals, loops, break and continue statements, switch statements, and unary operators. Let's dive in! 4 | 5 | ## Comparison Operators 6 | 7 | Comparison operators are used to compare two values and return a boolean value (true or false). Here are the commonly used comparison operators in JavaScript: 8 | 9 | - `>`: Greater than 10 | - `<`: Less than 11 | - `>=`: Greater than or equal to 12 | - `<=`: Less than or equal to 13 | - `!=`: Not equal to (type coercion) 14 | - `!==`: Not equal to (strict comparison) 15 | - `==`: Equal to (type coercion) 16 | - `===`: Equal to (strict comparison) 17 | 18 | ## String-Based Operators 19 | 20 | JavaScript provides a concatenation operator (`+`) to join two or more strings together. Here's an example: 21 | 22 | ```javascript 23 | console.log("Arvind " + "Pandit"); // Output: Arvind Pandit 24 | console.log("Js basics " + 2); // Output: Js basics 2 (coercion discussed later) 25 | ``` 26 | 27 | ## Bitwise Operators 28 | 29 | Bitwise operators manipulate the binary representation of numbers. Here are the bitwise operators available in JavaScript: 30 | 31 | - `&`: Bitwise AND 32 | - `|`: Bitwise OR 33 | - `^`: Bitwise XOR 34 | - `~`: Bitwise NOT 35 | - `<<`: Left shift 36 | - `>>`: Right shift 37 | 38 | ## Ternary Operator 39 | 40 | The ternary operator provides a concise way to write conditional statements. It takes three operands: a condition, a value to be returned if the condition is true, and a value to be returned if the condition is false. Here's an example: 41 | 42 | ```javascript 43 | 2 < 1 ? console.log("Arvind") : console.log("Pandit"); // Output: Pandit 44 | ``` 45 | 46 | ## Conditionals 47 | 48 | Conditionals in JavaScript allow you to execute different blocks of code based on certain conditions. The most common conditional statement is the `if` statement. Here's an example: 49 | 50 | ```javascript 51 | let x = 10; 52 | 53 | if (x >= 10) { 54 | console.log("Greater than or equal to 10"); 55 | } else { 56 | console.log("Less than 10"); 57 | } 58 | ``` 59 | 60 | Additionally, you can use the `if-else if-else` structure for multiple conditions. 61 | 62 | ## Loops 63 | 64 | Loops allow you to repeatedly execute a block of code. JavaScript provides two commonly used loop structures: `for` and `while` loops. 65 | 66 | ### `for` Loop 67 | 68 | The `for` loop repeats a block of code for a specified number of times. Here's an example: 69 | 70 | ```javascript 71 | for (let i = 0; i <= 10; i++) { 72 | console.log(i); 73 | } 74 | ``` 75 | 76 | ### `while` Loop 77 | 78 | The `while` loop repeats a block of code as long as a specified condition is true. Here's an example: 79 | 80 | ```javascript 81 | let x = 0; 82 | while (x <= 10) { 83 | console.log(x); 84 | x++; 85 | } 86 | ``` 87 | 88 | ## Break and Continue 89 | 90 | The `break` statement is used to exit the nearest enclosing loop or switch statement. The `continue` statement skips the current iteration and proceeds to the next iteration. Here are some examples: 91 | 92 | ```javascript 93 | for (let i = 0; i <= 10; i++) { 94 | if (i == 5) { 95 | console.log("Breaking out the nearest loop"); 96 | break; 97 | } else { 98 | console.log(i); 99 | } 100 | } 101 | 102 | let text = ""; 103 | for (let i = 0; i < 10; i++) { 104 | if (i <= 3) { 105 | continue; 106 | } 107 | text = text + i; 108 | } 109 | console.log(text); 110 | ``` 111 | 112 | ## Switch Statement 113 | 114 | The `switch` statement allows you to perform different actions based on different conditions. Here's an example: 115 | 116 | ```javascript 117 | let day = "wednesday"; 118 | 119 | switch (day) { 120 | case "monday": 121 | console.log("Monday"); 122 | break; 123 | case "tuesday": 124 | console.log("Tuesday"); 125 | break; 126 | case "sunday": 127 | console.log("Sunday"); 128 | break; 129 | default: 130 | console.log("Not a valid day"); 131 | } 132 | ``` 133 | 134 | ## Unary Operators 135 | 136 | Unary operators are used to perform operations on a single operand. Some commonly used unary operators in JavaScript are: 137 | 138 | - `x++`: Post-increment 139 | - `++x`: Pre-increment 140 | - `x--`: Post-decrement 141 | - `--x`: Pre-decrement 142 | 143 | Let's see some examples: 144 | 145 | ```javascript 146 | let x = 10; 147 | let y = x++; 148 | 149 | console.log(y); // Output: 10 150 | console.log(x); // Output: 11 151 | 152 | let m = 100; 153 | let c = m--; 154 | 155 | console.log(c); // Output: 100 156 | console.log(m); // Output: 99 157 | ``` 158 | 159 | In the first example, `x++` is a post-increment operator, which means the value of `x` is first assigned to `y`, and then `x` is incremented by 1. 160 | 161 | In the second example, `m--` is a post-decrement operator, which means the value of `m` is first assigned to `c`, and then `m` is decremented by 1. 162 | 163 | Remember that post-increment and post-decrement operators first assign the current value and then perform the increment or decrement operation. 164 | 165 | ## Conclusion 166 | 167 | In this readme file, we explored various operators and control flow statements in JavaScript. We discussed comparison operators, string-based operators, bitwise operators, the ternary operator, conditionals, loops, break and continue statements, switch statements, and unary operators. Understanding these concepts will greatly enhance your ability to write powerful and efficient JavaScript code. 168 | -------------------------------------------------------------------------------- /01 Intro to JS/03 Coercion/Codes/toNumber_demo.js: -------------------------------------------------------------------------------- 1 | //abstract operator - toNumber() 2 | 3 | //subtraction operator calls the toNumber() method bts, so let's mimic it using substraction operator 4 | 5 | console.log(5 - 6); 6 | //both values are number so the output will be -1 7 | 8 | console.log("7" - 5); 9 | /** 10 | * here, the left value (lval) is a string and the rval is a number 11 | * so, js implicitly convert "7" to 7 12 | * 7 - 5 = 2 13 | */ 14 | 15 | console.log(true - false); 16 | /* 17 | * the lval and rval both are boolean 18 | * so both values undergo toNumber() abstract operation 19 | * true -> 1 & false -> 0 20 | * 1 - 0 = 1 21 | */ 22 | 23 | console.log(undefined - 1); 24 | /** 25 | * the lval is undefined (not a number) 26 | * so it will undergo toNumber abstract operation 27 | * undefined -> NaN 28 | * NaN - 1 = NaN 29 | */ 30 | 31 | console.log(3 - null); 32 | /** 33 | * the rval is null, so it will undergo abstract operation 34 | * null -> 0 35 | * 3 - 0 = 3 36 | */ 37 | 38 | console.log(undefined - null); 39 | /** 40 | * both the values are not number so they undergo toNumber abstract operation 41 | * undefined -> NaN null -> 0 42 | * NaN - 0 = NaN 43 | */ 44 | 45 | console.log("7" - "5"); 46 | /** 47 | * both will undergo toNumber abs op. 48 | * 7 - 5 = 2 49 | */ 50 | 51 | console.log("arvind" - 4); 52 | /** 53 | * lval is not a number so it will undergo toNumber abstract operation 54 | * "arvind" -> NaN 55 | * NaN - 4 = NaN 56 | */ 57 | -------------------------------------------------------------------------------- /01 Intro to JS/03 Coercion/Codes/toNumber_demo2.js: -------------------------------------------------------------------------------- 1 | // + -> toString (if any value is string {basically tries to concatenate}) 2 | // - -> toNumber abstract operator 3 | 4 | //let's play with non primitive data type like objects and arrays 5 | 6 | console.log(5 - { a: 6 }); 7 | /** 8 | * reason- 9 | * the rval is an object not a primitive so it will undergo toPrimitive abstract operation 10 | * hint variable is initialized with preferredType 'number' 11 | * now it call OrdinaryToPrimitive(input, preferredType). 12 | * 13 | * since , hint is a number 14 | * - valueOf is called 15 | * - toString is called 16 | * 17 | * valueOf return the same object {a : 6} 18 | * to string will return '[object Object]' which is primitive 19 | * So call ToNumber on '[object Object]' again which gives NaN 20 | * 21 | * 5 - NaN 22 | * NaN 23 | */ 24 | 25 | console.log("arvind" + { a: 10 }); 26 | /** 27 | * reason- 28 | * the rval is an object not a primitive so it will undergo toPrimitive abstract operation 29 | * hint variable is initialized with preferredType 'number' 30 | * now it call OrdinaryToPrimitive(input, preferredType). 31 | * 32 | * since , hint is a number 33 | * - valueOf is called 34 | * - toString is called 35 | * * 36 | * 37 | * we first call valueOf on {"a" : 10} -> and it returns same object 38 | * we call toString -> toStrign will return '[object Object]' which is a string i.e. primitive 39 | * 40 | * "arvind" + "[object Object]" 41 | * arvind[object Object] 42 | */ 43 | 44 | console.log( 45 | "arvind" + 46 | { 47 | a: 10, 48 | valueOf() { 49 | return "pandit"; 50 | }, 51 | } 52 | ); 53 | //arvindpandit 54 | 55 | console.log( 56 | 7 + 57 | { 58 | x: 10, 59 | valueOf() { 60 | return 8; 61 | }, 62 | } 63 | ); 64 | 65 | //15 66 | 67 | console.log( 68 | "arvind" + 69 | { 70 | a: 10, 71 | valueOf() { 72 | return {}; 73 | }, 74 | toString() { 75 | return "pandit"; 76 | }, 77 | } 78 | ); 79 | //arvindpandit 80 | 81 | console.log( 82 | 7 - 83 | { 84 | x: 10, 85 | valueOf() { 86 | return 8; 87 | }, 88 | } 89 | ); 90 | 91 | //-1 92 | -------------------------------------------------------------------------------- /01 Intro to JS/03 Coercion/Codes/toString_demo.js: -------------------------------------------------------------------------------- 1 | // addition operator calls toString bts, so let's mimic it using '+' operator 2 | //The addition operator either performs string concatenation - if one val is string 3 | //or numeric addition. 4 | 5 | console.log(3 + 5); 6 | /** 7 | * since, both the values are number so it will add the number 8 | */ 9 | 10 | console.log(7 + "6"); 11 | /** 12 | * since , the rval is a string so it will convert the lval to string using toString abstract operation 13 | * 7 -> "7" 14 | * "7" + "6" = "76" 15 | */ 16 | 17 | console.log(typeof (7 + "6")); //string , got it! 18 | console.log(typeof (3 + 5)); //number , got it! 19 | 20 | console.log(undefined + "7"); // "undefined7" 21 | console.log(undefined + 7); // "NaN" 22 | 23 | console.log(true + 5); 24 | /** 25 | * since, none of the values are string so it will try to concatenate 26 | * true will undergo toNumber abstract operation 27 | * true -> 1 28 | * 1 + 5 = 6 29 | */ 30 | 31 | console.log(null + undefined); 32 | /** 33 | * undefined -> NaN null -> 0 34 | * 0 + NaN = NaN 35 | */ 36 | 37 | console.log("null" + undefined); //null undefined 38 | -------------------------------------------------------------------------------- /01 Intro to JS/03 Coercion/Notes/Coercion.md: -------------------------------------------------------------------------------- 1 | # Coercion 2 | 3 | Coercion in programming refers to the process of converting one type of value to another type. It involves type interconversion, where values are transformed from their original type to a different type, either explicitly or implicitly. Coercion is a fundamental concept in many programming languages, including JavaScript. 4 | 5 | This type interconversion can be done: 6 | 7 | - Explicitly: when we manually command to convert types. 8 | - Implicitly: when the language automatically converts types. 9 | 10 | Note: In languages like C, C++, and Java, types exist for variables. For example, in C++: 11 | 12 | ```cpp 13 | int age = 10; 14 | bool authentication = false; 15 | ``` 16 | 17 | But in JavaScript, types exist for the values: 18 | 19 | ```javascript 20 | let age = 10; 21 | let name = "arvindPandit"; 22 | ``` 23 | 24 | ### How JS handles coercion? 25 | 26 | Let's first learn about abstract operations. 27 | They are internal algorithms of ECMAScript/JS that end-users cannot use directly. They are made to understand the documentation. Some examples of abstract operations include: 28 | 29 | - ToNumber 30 | - ToString 31 | - ToBoolean 32 | - ToPrimitive 33 | 34 | Note: We cannot directly call these abstract operators, but a few JS operations like subtraction (-), addition (+), etc., internally call them. Hence, we can mimic them using these operations. 35 | 36 | ### ToNumber 37 | 38 | We can use the subtraction operation (-) to mimic the ToNumber abstract operation. 39 | ECMAScript documentation link: [ToNumber](https://262.ecma-international.org/13.0/#sec-tonumber) 40 | 41 | Note: Subtraction always converts both operands to a number. 42 | 43 | Let's consider two variables, `a` and `b`, and do `a - b`: 44 | Here, `a` is lval (left value), and `b` is rval (right value). 45 | 46 | If any of the operands is not a number, it will undergo the ToNumber abstract operation: 47 | 48 | - `lnum = ToNumber(a)` 49 | - `rnum = ToNumber(b)` 50 | 51 | Return `lnum - rnum`. 52 | 53 | ### Some string to number conversion examples: 54 | 55 | - "" ➡️ 0 56 | - "0" ➡️ 0 57 | - "arvind" ➡️ NaN 58 | - "009" ➡️ 9 59 | - "24.4" ➡️ 24.4 60 | - "." ➡️ NaN 61 | - "$" ➡️ NaN 62 | 63 | ### Array to number conversion examples: 64 | 65 | - [""] ➡️ 0 66 | - [] ➡️ NaN 67 | - [null] ➡️ 0 68 | - [1,2,3] ➡️ NaN 69 | - [[[]]] ➡️ 0 70 | 71 | ### Coercion Examples in JavaScript 72 | 73 | Now, let's explore some examples of coercion in JavaScript using the subtraction operator: 74 | 75 | ```javascript 76 | console.log(5 - 6); 77 | // Output: -1 78 | // Both values are numbers, so the output will be -1 79 | 80 | console.log("7" - 5); 81 | // Output: 2 82 | // Here, the lval is a string and the rval is a number. 83 | // JS implicitly converts "7" to 7: 7 - 5 = 2 84 | 85 | console.log(true - false); 86 | // Output: 1 87 | // Both lval and rval are booleans. 88 | // Both values undergo the ToNumber abstract operation: 89 | // true ➡️ 1 and false ➡️ 0: 1 - 0 = 1 90 | 91 | console.log(undefined - 1); 92 | // Output: NaN 93 | // The lval is undefined (not a number). 94 | // It undergoes the ToNumber abstract operation: undefined ➡️ NaN 95 | // NaN - 1 = NaN 96 | 97 | console.log(3 - null); 98 | // Output: 3 99 | // The rval is null, so it undergoes the ToNumber abstract operation: null ➡️ 0 100 | // 3 - 0 = 3 101 | 102 | console.log(undefined - null); 103 | // Output: NaN 104 | // Both values are not 105 | //numbers, so they undergo the ToNumber abstract operation: 106 | // undefined ➡️ NaN and null ➡️ 0: NaN - 0 = NaN 107 | 108 | console.log("7" - "5"); 109 | // Output: 2 110 | // Both values undergo the ToNumber abstract operation: 7 - 5 = 2 111 | 112 | console.log("arvind" - 4); 113 | // Output: NaN 114 | // The lval is not a number, so it undergoes the ToNumber abstract operation: "arvind" ➡️ NaN 115 | // NaN - 4 = NaN 116 | ``` 117 | 118 | ### Conclusion 119 | 120 | Coercion is an essential concept in JavaScript, allowing for type interconversion. By understanding the behavior of abstract operations like ToNumber and leveraging certain operators like subtraction, we can effectively perform type conversions in JS. Coercion can be explicit, where we manually command the type conversion, or implicit, where the language automatically converts types based on context. Being aware of how coercion works is crucial for writing robust and predictable JavaScript code. 121 | -------------------------------------------------------------------------------- /01 Intro to JS/03 Coercion/Notes/Coercion2.md: -------------------------------------------------------------------------------- 1 | # Coercion-2: ToString 2 | 3 | In the previous sections, we explored the concept of coercion, abstract operations, and ToNumber conversion in JavaScript. Now, let's dive into another important abstract operation called ToString. ToString is responsible for converting values to their string representations. 4 | 5 | ## Using the Addition Operator for ToString 6 | 7 | In JavaScript, we can mimic the ToString abstract operation using the addition operator (+). The addition operator performs either string concatenation or numeric addition, depending on the types of the operands involved. 8 | 9 | ## Conversion Process with ToString 10 | 11 | Consider two variables, `a` and `b`, and perform the operation `a + b`. Here, `a` represents the lval (left value), and `b` represents the rval (right value). 12 | 13 | If either operand is not a number, it will undergo the ToPrimitive abstract operation: 14 | 15 | - `lprim = ToPrimitive(a)` 16 | - `rprim = ToPrimitive(b)` 17 | 18 | If `lprim` or `rprim` is a string, the operation will perform string concatenation. Otherwise, both `lprim` and `rprim` are converted to numbers using the ToNumber abstract operation: 19 | 20 | - `lnum = ToNumber(lprim)` 21 | - `rnum = ToNumber(rprim)` 22 | 23 | Finally, the result is obtained by performing the numeric addition (`lnum + rnum`). 24 | 25 | ## String Conversion Examples 26 | 27 | Here are some examples of string conversion using ToString: 28 | 29 | - `null` ➡️ `"null"` 30 | - `undefined` ➡️ `"undefined"` 31 | - `true` ➡️ `"true"` 32 | - `2.3` ➡️ `"2.3"` 33 | - `0` ➡️ `"0"` 34 | - `-0` ➡️ `"0"` 35 | - `[]` ➡️ `""` 36 | - `[1,2,3]` ➡️ `"1,2,3"` 37 | - `[null, undefined]` ➡️ `","` 38 | - `[[], [], []]` ➡️ `", , ,"` 39 | - `[,,,]` ➡️ `",,,"` 40 | 41 | ## Examples of ToString Conversion 42 | 43 | Let's explore some examples of ToString conversion in JavaScript using the addition operator: 44 | 45 | ```javascript 46 | console.log(3 + 5); 47 | // Output: 8 48 | // Since both values are numbers, they are added together: 3 + 5 = 8 49 | 50 | console.log(7 + "6"); 51 | // Output: "76" 52 | // The rval is a string, so the lval is converted to a string using the ToString abstract operation: 53 | // 7 ➡️ "7" 54 | // "7" + "6" = "76" 55 | 56 | console.log(typeof (7 + "6")); // Output: "string" 57 | console.log(typeof (3 + 5)); // Output: "number" 58 | 59 | console.log(undefined + "7"); // Output: "undefined7" 60 | console.log(undefined + 7); // Output: "NaN" 61 | 62 | console.log(true + 5); 63 | // Output: 6 64 | // Since both values are not strings, the operation tries to perform string concatenation. 65 | // The true value undergoes the ToNumber abstract operation: true ➡️ 1 66 | // 1 + 5 = 6 67 | 68 | console.log(null + undefined); 69 | // Output: NaN 70 | // undefined ➡️ NaN and null ➡️ 0 71 | // 0 + NaN = NaN 72 | 73 | console.log("null" + undefined); // Output: "nullundefined" 74 | ``` 75 | 76 | By understanding the ToString abstract operation and utilizing the addition operator, we can effectively convert values to their string representations in JavaScript. 77 | -------------------------------------------------------------------------------- /01 Intro to JS/03 Coercion/Notes/Coercion3.md: -------------------------------------------------------------------------------- 1 | # Coercion 3 - ToPrimitive 2 | 3 | In JavaScript, the ToPrimitive function is responsible for converting an input argument into a non-object type, also known as a primitive type. If the conversion is not possible, it throws a TypeError. 4 | 5 | ToPrimitive takes an optional parameter called preferredType, which helps determine the preferred type of the result if multiple values are possible. If preferredType is not provided, a hint variable is automatically initialized and set to the default. If preferredType is "string", the hint is set to "string". If preferredType is "number", the hint is set to "number". 6 | 7 | The conversion process depends on the hint value: 8 | 9 | ## Hint is String 10 | 11 | If the hint is "string", ToPrimitive first calls the toString method on the input value. If the result is a non-object, it is returned. If the result is an object, the valueOf method is called. If the result of valueOf is a non-object, it is returned. If the result is still an object, a TypeError is thrown. 12 | 13 | ## Hint is Number 14 | 15 | If the hint is "number", ToPrimitive first calls the valueOf method on the input value. If the result is a non-object, it is returned. If the result is an object, the toString method is called. If the result of toString is a non-object, it is returned. If the result is still an object, a TypeError is thrown. 16 | 17 | Certainly! Here's a tree diagram for the conversion process with the hint as "string" or "number": 18 | 19 | ``` 20 | ToPrimitive (hint: string) 21 | | 22 | | 23 | v 24 | toString() 25 | / \ 26 | Primitive Value Object 27 | | (Call toString) 28 | | | 29 | | | 30 | v v 31 | Non-Object Result Primitive Result 32 | (Return) (Return) 33 | 34 | 35 | ToPrimitive (hint: number) 36 | | 37 | | 38 | v 39 | valueOf() 40 | / \ 41 | Primitive Value Object 42 | | (Call valueOf) 43 | | | 44 | | | 45 | v v 46 | Non-Object Result Primitive Result 47 | (Return) (Return) 48 | ``` 49 | 50 | In this tree diagram, the process starts with the ToPrimitive function at the top. When the hint is "string", it directly calls the toString method. If the result is a non-object, it returns the primitive value as the final result. If the result is an object, it continues to the "Object (Call toString)" branch, where the toString method is called on the object. Again, if the result is a non-object, it returns the primitive value. If the result is still an object, it indicates an error. 51 | 52 | Similarly, when the hint is "number", the process starts with the valueOf method. If the result is a non-object, it returns the primitive value as the final result. If the result is an object, it continues to the "Object (Call valueOf)" branch, where the valueOf method is called on the object. Once again, if the result is a non-object, it returns the primitive value. If the result is still an object, it indicates an error. 53 | 54 | This tree diagram provides a clearer representation of the conversion process, showcasing the paths taken and the final results for both "string" and "number" hints. 55 | 56 | Note: valueOf and toString are not abstract operations and can be called directly. 57 | 58 | By default, for objects: 59 | 60 | - toString returns "[object Object]" 61 | - valueOf returns the same object 62 | 63 | By default, for arrays: 64 | 65 | - toString prints the array without the brackets 66 | - valueOf returns the same array 67 | 68 | EcmaScript Documentation Link: https://262.ecma-international.org/13.0/#sec-toprimitive 69 | 70 | ## Examples of ToPrimitive Conversion 71 | 72 | Let's explore some examples of ToPrimitive conversion using objects and arrays in JavaScript: 73 | 74 | ```javascript 75 | console.log(5 - { a: 6 }); 76 | // Output: NaN 77 | // The rval is an object, so it undergoes the ToPrimitive abstract operation. 78 | // Since the hint is 'number', valueOf and toString are called. 79 | // valueOf returns the same object { a: 6 } 80 | // toString returns '[object Object]', which is a primitive. 81 | // '[object Object]' is then converted to NaN using the ToNumber operation. 82 | // 5 - NaN = NaN 83 | 84 | console.log("arvind" + { a: 10 }); 85 | // Output: "arvind[object Object]" 86 | // The rval is an object, so it undergoes the ToPrimitive abstract operation. 87 | // Since the hint is 'number', valueOf and toString are called. 88 | // valueOf returns the same object { a: 10 } 89 | // toString returns '[object Object]', which is a string (primitive). 90 | // "arvind" + "[object Object]" = "arvind[object Object]" 91 | 92 | console.log( 93 | "arvind" + 94 | { 95 | a: 10, 96 | valueOf() { 97 | return "pandit"; 98 | }, 99 | } 100 | ); 101 | // Output: "arvindpandit" 102 | // The rval is an object, so it undergoes the ToPrimitive abstract operation. 103 | // Since the hint is 'number', valueOf and toString are called. 104 | // valueOf returns "pandit", which is a non-object. 105 | // "arvind" + "pandit" = "arvindpandit" 106 | 107 | console.log( 108 | 7 + 109 | { 110 | x: 10, 111 | valueOf() { 112 | return 8; 113 | }, 114 | } 115 | ); 116 | // Output: 15 117 | // The rval is an object, so it undergoes the ToPrimitive abstract operation. 118 | // Since the hint is 'number', valueOf and toString are called. 119 | // valueOf returns 8, which is a non object. 120 | // 7 + 8 = 15 121 | 122 | console.log( 123 | "arvind" + 124 | { 125 | a: 10, 126 | valueOf() { 127 | return {}; 128 | }, 129 | toString() { 130 | return "pandit"; 131 | }, 132 | } 133 | ); 134 | // Output: "arvindpandit" 135 | // The rval is an object, so it undergoes the ToPrimitive abstract operation. 136 | // Since the hint is 'number', valueOf and toString are called. 137 | // valueOf returns an empty object, which is still an object. 138 | // toString returns "pandit", which is a non-object. 139 | // "arvind" + "pandit" = "arvindpandit" 140 | 141 | console.log( 142 | 7 - 143 | { 144 | x: 10, 145 | valueOf() { 146 | return 8; 147 | }, 148 | } 149 | ); 150 | // Output: -1 151 | // The rval is an object, so it undergoes the ToPrimitive abstract operation. 152 | // Since the hint is 'number', valueOf and toString are called. 153 | // valueOf returns 8, which is a non-object. 154 | // 7 - 8 = -1 155 | ``` 156 | 157 | By understanding the ToPrimitive function and its conversion process, we can handle coercion in JavaScript and ensure the correct conversion of values into non-object types. 158 | -------------------------------------------------------------------------------- /02 Advance JS/05 ToBoolean & Strict Equality/Codes/Strict_equality.js: -------------------------------------------------------------------------------- 1 | console.log(7 === 7); 2 | 3 | console.log(NaN === NaN); 4 | /** 5 | * in JS , NaN is the only primitive value not equal to itself 6 | */ 7 | 8 | let x = NaN; 9 | console.log(x === x); //false as per the above rule 10 | 11 | console.log(undefined === undefined); 12 | console.log(null === null); 13 | 14 | console.log({} === {}); 15 | /** 16 | * these two objects are at different memomy location 17 | * hence, they wont be equal 18 | * false 19 | */ 20 | 21 | let y = { a: "arvind" }; 22 | console.log(y === y); 23 | /** 24 | * here y indicates the {a : "arvind"} 25 | * so it will give true 26 | */ 27 | 28 | console.log(-0 === 0); //true 29 | -------------------------------------------------------------------------------- /02 Advance JS/05 ToBoolean & Strict Equality/Codes/ToBoolean.js: -------------------------------------------------------------------------------- 1 | /** 2 | * List of falsy values 3 | * null 4 | * undefined 5 | * +0 6 | * -0 7 | * NaN 8 | * "" (empty string) 9 | * false 10 | * 11 | * expect all these , everthing is a truthy values 12 | */ 13 | 14 | //testing ToBoolean operator, we use logical NOT operator (!) 15 | 16 | console.log(!3); 17 | /** 18 | * 3 is truthy 19 | * 3 -> true 20 | * !3 -> false 21 | */ 22 | 23 | console.log(!0); 24 | /** 25 | * 0 is falsy 26 | * 0 -> false 27 | * !0 -> true 28 | */ 29 | 30 | console.log(!undefined); 31 | /** 32 | * undefined is fasly 33 | * undefined -> false 34 | * !undefined -> true 35 | * 36 | */ 37 | 38 | console.log(!NaN); 39 | /** 40 | * NaN is fasly 41 | * NaN -> false 42 | * !NaN -> true 43 | * 44 | */ 45 | 46 | console.log(!"arvind"); //false 47 | console.log(!""); //true 48 | 49 | console.log(!("arvind" || 0)); //false 50 | console.log(!("arvind" && 0)); //true 51 | console.log(!(0 && "arvind")); //true 52 | 53 | console.log(!{}); 54 | /** 55 | * object -> true 56 | * false 57 | */ 58 | -------------------------------------------------------------------------------- /02 Advance JS/05 ToBoolean & Strict Equality/Notes/ToBoolean_strict_operator.md: -------------------------------------------------------------------------------- 1 | # Coercion 4 - ToBoolean & Equality Operator 2 | 3 | ## ToBoolean 4 | 5 | The ToBoolean abstract operation converts the given type to a boolean value. ToBoolean works differently compared to ToString or ToNumber. It maintains a list of values that, when received as an argument, return false (known as falsy values), while everything else returns true (known as truthy values). 6 | 7 | List of falsy values: 8 | 9 | - null 10 | - undefined 11 | - +0 12 | - -0 13 | - NaN 14 | - "" (empty string) 15 | - false 16 | 17 | If any of these values are present in the argument, ToBoolean returns false; otherwise, it returns true. 18 | 19 | We can test the ToBoolean operation using the logical NOT operator (!). 20 | 21 | Example: 22 | 23 | ```javascript 24 | !a 25 | oldValue = ToBoolean(a); 26 | if (oldValue is True) return false; 27 | else return true; 28 | ``` 29 | 30 | You can read more about the ToBoolean operation in the [ECMAScript specification Section 7.1.2: ToBoolean](https://262.ecma-international.org/13.0/#sec-toboolean). 31 | 32 | ## Equality Operator 33 | 34 | The equality operator in JavaScript comes in two forms: strict equality (`===`) and abstract equality (`==`). 35 | 36 | The main difference between `==` and `===` is that `==` performs type coercion if the types are not the same, while `===` strictly compares both the values and types without any coercion. 37 | 38 | Strict equality examples: 39 | 40 | ```javascript 41 | console.log(7 === 7); // true 42 | 43 | console.log(NaN === NaN); 44 | /** 45 | * In JavaScript, NaN is the only primitive value not equal to itself. 46 | */ 47 | 48 | let x = NaN; 49 | console.log(x === x); // false (as per the above rule) 50 | 51 | console.log(undefined === undefined); // true 52 | console.log(null === null); // true 53 | 54 | console.log({} === {}); 55 | /** 56 | * These two objects are at different memory locations, 57 | * hence they won't be equal. 58 | * false 59 | */ 60 | 61 | let y = { a: "arvind" }; 62 | console.log(y === y); 63 | /** 64 | * Here, y indicates the {a: "arvind"} object, 65 | * so it will give true. 66 | */ 67 | 68 | console.log(-0 === 0); // true 69 | ``` 70 | 71 | In JavaScript, NaN is the only primitive value not equal to itself. 72 | 73 | By understanding the concepts of ToBoolean and the Equality Operator, we can effectively convert values to booleans and compare values with different equality operators, considering both type and value aspects. 74 | 75 | You can refer to the [ECMAScript specification Section 7.1.2: ToBoolean](https://262.ecma-international.org/13.0/#sec-toboolean) for more information on ToBoolean, and the [ECMAScript specification Section 7.2.14: Strict Equality Comparison](https://262.ecma-international.org/13.0/#sec-isstrictlyequal) for more details on the strict equality operator. 76 | -------------------------------------------------------------------------------- /02 Advance JS/06 Abstract equality, NaN, Special Types/Codes/Number.isNaN_demo.js: -------------------------------------------------------------------------------- 1 | // Number.isNaN() -> does not do coersion 2 | 3 | console.log(Number.isNaN(NaN)); 4 | console.log(Number.isNaN(Infinity)); 5 | console.log(Number.isNaN("arvind")); 6 | -------------------------------------------------------------------------------- /02 Advance JS/06 Abstract equality, NaN, Special Types/Codes/abstract_equality_demo.js: -------------------------------------------------------------------------------- 1 | // If x is null and y is undefined, return true. 2 | console.log(null == undefined); 3 | //If x is undefined and y is null, return true. 4 | console.log(undefined == null); 5 | 6 | //If Type(x) is Number and Type(y) is String, return ! IsLooselyEqual(x, ! ToNumber(y)). 7 | console.log(7 == "7"); //ToNumber('7') -> 7 => 7 == 7 => true 8 | console.log(7 == "seven"); //ToNumber("seven") => NaN => false 9 | 10 | // If Type(x) is String and Type(y) is Number, return ! IsLooselyEqual(! ToNumber(x), y). 11 | console.log("10" == 10); 12 | 13 | //If Type(x) is Boolean, return ! IsLooselyEqual(! ToNumber(x), y). 14 | console.log(false == 0); //ToNumber(false) ->return 0 => true 15 | 16 | //If x or y are any of NaN, +∞𝔽, or -∞𝔽, return false. 17 | console.log(NaN == NaN); 18 | console.log(undefined == undefined); //true 19 | 20 | // If Type(x) is either String, Number, BigInt, or Symbol and Type(y) is Object, return ! IsLooselyEqual(x, ? ToPrimitive(y)). 21 | 22 | console.log(10 == { a: 10 }); //false 23 | console.log( 24 | 10 == 25 | { 26 | valueOf() { 27 | return 10; 28 | }, 29 | } 30 | ); //true 31 | 32 | console.log( 33 | "arvind" == 34 | { 35 | a: 10, 36 | valueOf() { 37 | return 10; 38 | }, 39 | toString() { 40 | return "arvind"; 41 | }, 42 | } 43 | ); //false 44 | 45 | console.log( 46 | "arvind" == 47 | { 48 | a: 10, 49 | valueOf() { 50 | return {}; 51 | }, 52 | toString() { 53 | return "arvind"; 54 | }, 55 | } 56 | ); //true 57 | -------------------------------------------------------------------------------- /02 Advance JS/06 Abstract equality, NaN, Special Types/Codes/isNaN_demo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * isNaN is coerces the argument before checking for NaN 3 | */ 4 | 5 | let a = "arvind"; 6 | console.log(isNaN(a)); 7 | /** 8 | * isNaN("arvind") 9 | * isNaN coerces the string "arvind" -> ToNumber("arvind") -> NaN 10 | * so it will print true 11 | */ 12 | 13 | let b = undefined; 14 | console.log(isNaN(b)); //ToNumber(undefined) -> NaN 15 | 16 | let c = Infinity; 17 | console.log(isNaN(c)); //false 18 | 19 | let d = "arvind"; 20 | typeof d == "number" && isNaN(d) ? console.log("NaN") : console.log("Not NaN"); 21 | -------------------------------------------------------------------------------- /02 Advance JS/06 Abstract equality, NaN, Special Types/Codes/truthy_falsy_demo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * List of falsy values 3 | * null 4 | * undefined 5 | * +0, -0 6 | * NaN 7 | * "" (empty string) 8 | * false 9 | * 10 | * except these values everything is truthy in JS* 11 | * 12 | */ 13 | 14 | let a = true; 15 | 16 | if (a) { 17 | console.log("hello arvind"); 18 | } 19 | if (a == 1) { 20 | // a is boolean so it will undergo ToNumber abstract operation 21 | // ToNumber(true) --> 1 22 | // 1 == 1 23 | // it will print the below string 24 | console.log("js is beautiful"); 25 | } 26 | 27 | let b = "arvind"; 28 | 29 | if (b) { 30 | console.log("arvind"); 31 | } 32 | if (b == NaN) { 33 | // b is string it will undergo ToNumber("arvind") -> NaN 34 | // NaN == NaN 35 | //false 36 | //won't print the output 37 | console.log("js is interesting"); 38 | } 39 | -------------------------------------------------------------------------------- /02 Advance JS/06 Abstract equality, NaN, Special Types/Notes/Abstract_operator_NaN.md: -------------------------------------------------------------------------------- 1 | # Coercion 5 - Abstract equality & NaN 2 | 3 | ## Abstract Equality 4 | 5 | Abstract equality (`==`) in JavaScript first checks whether the types of the left and right operands are the same. If they are of the same type, it calls strict equality (`===`). If the types are not the same, it performs an algorithm known as the Abstract Equality Comparison, which is defined in the [ECMAScript specification Section 7.2.14: IsLooselyEqual](https://262.ecma-international.org/13.0/#sec-islooselyequal). 6 | 7 | Some examples of abstract equality comparisons: 8 | 9 | ```javascript 10 | // If x is null and y is undefined, return true. 11 | console.log(null == undefined); 12 | //If x is undefined and y is null, return true. 13 | console.log(undefined == null); 14 | 15 | //If Type(x) is Number and Type(y) is String, return ! IsLooselyEqual(x, ! ToNumber(y)). 16 | console.log(7 == "7"); //ToNumber('7') -> 7 => 7 == 7 => true 17 | console.log(7 == "seven"); //ToNumber("seven") => NaN => false 18 | 19 | // If Type(x) is String and Type(y) is Number, return ! IsLooselyEqual(! ToNumber(x), y). 20 | console.log("10" == 10); 21 | 22 | //If Type(x) is Boolean, return ! IsLooselyEqual(! ToNumber(x), y). 23 | console.log(false == 0); //ToNumber(false) ->return 0 => true 24 | 25 | //If x or y are any of NaN, +∞𝔽, or -∞𝔽, return false. 26 | console.log(NaN == NaN); 27 | console.log(undefined == undefined); //true 28 | 29 | // If Type(x) is either String, Number, BigInt, or Symbol and Type(y) is Object, return ! IsLooselyEqual(x, ? ToPrimitive(y)). 30 | 31 | console.log(10 == { a: 10 }); //false 32 | console.log( 33 | 10 == 34 | { 35 | valueOf() { 36 | return 10; 37 | }, 38 | } 39 | ); //true 40 | 41 | console.log( 42 | "arvind" == 43 | { 44 | a: 10, 45 | valueOf() { 46 | return 10; 47 | }, 48 | toString() { 49 | return "arvind"; 50 | }, 51 | } 52 | ); //false 53 | 54 | console.log( 55 | "arvind" == 56 | { 57 | a: 10, 58 | valueOf() { 59 | return {}; 60 | }, 61 | toString() { 62 | return "arvind"; 63 | }, 64 | } 65 | ); //true 66 | ``` 67 | 68 | You can learn more about the Abstract Equality Comparison algorithm in the [ECMAScript specification Section 7.2.14: IsLooselyEqual](https://262.ecma-international.org/13.0/#sec-islooselyequal). 69 | 70 | ## NaN 71 | 72 | NaN stands for "Not a Number," but it actually represents an invalid number. It is the result of operations that cannot produce a meaningful numeric value. 73 | 74 | NaN has some interesting characteristics: 75 | 76 | - NaN is the only primitive value in JavaScript that doesn't follow the identity property and is not equal to itself. 77 | - When comparing NaN with NaN using strict equality (`===`) or abstract equality (`==`), the result is always false. 78 | 79 | Additional functions related to NaN: 80 | 81 | - `isNaN`: The `isNaN` function coerces the argument before checking for NaN. It converts the argument to a number and then checks if it is NaN. However, be cautious when using `isNaN`, as it can produce unexpected results for non-numeric values. It's recommended to use `Number.isNaN` for more reliable NaN checks. 82 | - `Number.isNaN`: The `Number.isNaN` function is a more reliable way to check for NaN. It performs a strict check and does not perform any coercion. It returns true only if the provided value is exactly NaN. 83 | 84 | Here are the code snippets related to NaN: 85 | 86 | ```javascript 87 | // Using isNaN function 88 | let a = "arvind"; 89 | console.log(isNaN(a)); // true 90 | 91 | let b = undefined; 92 | console.log(isNaN(b)); // true 93 | 94 | let c = Infinity; 95 | console.log(isNaN(c)); // false 96 | 97 | let d = "arvind"; 98 | typeof d == "number" && isNaN(d) ? console.log("NaN") : console.log(" 99 | 100 | Not NaN"); 101 | 102 | // Using Number.isNaN function 103 | console.log(Number.isNaN(NaN)); // true 104 | console.log(Number.isNaN(Infinity)); // false 105 | console.log(Number.isNaN("arvind")); // false 106 | ``` 107 | 108 | Remember to handle NaN comparisons and checks with caution due to their unique behavior. 109 | 110 | ## Conclusion 111 | 112 | In this readme, we explored one of the most important topics in JavaScript: coercion. We learned about abstract operators like ToNumber, ToString, ToPrimitive, and ToBoolean. We also delved into the differences between strict equality (`===`) and abstract equality (`==`), as well as the peculiarities of NaN. 113 | 114 | Understanding coercion is crucial for writing robust and predictable code in JavaScript. Coercion plays a significant role in JavaScript's type system, influencing how values are compared and transformed. 115 | 116 | Feel free to experiment with different scenarios and refer to the ECMAScript specification for a comprehensive understanding of coercion and related concepts. 117 | 118 | Remember to always write clear and readable code, considering the behavior of coercion and choosing the appropriate equality operator based on your specific use case. 119 | -------------------------------------------------------------------------------- /02 Advance JS/07 Scopes/Codes/blockScope_demo.js: -------------------------------------------------------------------------------- 1 | { 2 | console.log(myName); //undefined 3 | var myName = "arvind"; 4 | console.log(myName); //arvind 5 | } 6 | /** 7 | * anywhere inside the block var myName can be used 8 | */ 9 | -------------------------------------------------------------------------------- /02 Advance JS/07 Scopes/Codes/const_demo.js: -------------------------------------------------------------------------------- 1 | const myName = "arvind"; 2 | myName = "arvind Pandit"; //cannot assign values to a const variable 3 | /** 4 | * behaves like let but reassignment is not possible in const 5 | */ 6 | -------------------------------------------------------------------------------- /02 Advance JS/07 Scopes/Codes/functionScope_demo.js: -------------------------------------------------------------------------------- 1 | var myName = "arvind"; //global scope 2 | 3 | function printName() { 4 | console.log(myName); //undefined 5 | /** 6 | * when js comes to the execution phase 7 | * myName variable exists in the scope printName function 8 | * but it is not assigned any value here 9 | * so "undefined" will be printed 10 | */ 11 | var myName = "arvind pandit"; //scope of printName 12 | console.log(myName); 13 | /** 14 | * when js comes to the execution phase 15 | * myName variable exists in the scope printName function 16 | * and it has assigned the value "arvind pandit" 17 | * so "arvind pandit" will be printed 18 | */ 19 | } 20 | 21 | console.log(myName); 22 | printName(); 23 | -------------------------------------------------------------------------------- /02 Advance JS/07 Scopes/Codes/globalScope_demo.js: -------------------------------------------------------------------------------- 1 | console.log(myName); 2 | /** 3 | * when js comes to the execution phase 4 | * myName variable exists in the global scope 5 | * but it is not assigned any value here 6 | * so "undefined" will be printed 7 | */ 8 | 9 | var myName = "arvind"; //global scope 10 | 11 | function printName() { 12 | console.log(myName); 13 | } 14 | 15 | printName(); 16 | -------------------------------------------------------------------------------- /02 Advance JS/07 Scopes/Codes/let_demo.js: -------------------------------------------------------------------------------- 1 | let myName = "arvind"; 2 | 3 | function printName() { 4 | console.log(userName); //Cannot access 'userName' before initialization 5 | let userName = "arvind pandit"; 6 | console.log(myName); 7 | } 8 | 9 | printName(); 10 | -------------------------------------------------------------------------------- /02 Advance JS/07 Scopes/Codes/lexicalScope1.js: -------------------------------------------------------------------------------- 1 | var myName = "arvind"; 2 | 3 | function printMathsMarks() { 4 | var mathsMarks = 99; 5 | console.log(myName); //arvind 6 | console.log(mathsMarks); //99 7 | } 8 | 9 | printMathsMarks(); 10 | -------------------------------------------------------------------------------- /02 Advance JS/07 Scopes/Codes/lexicalScope2.js: -------------------------------------------------------------------------------- 1 | var myName = "arvind"; 2 | 3 | console.log(myName); //arvind 4 | console.log(mathsMarks); //error : mathsMarks is not defined 5 | 6 | function printMathsMarks() { 7 | var mathsMarks = 99; 8 | console.log(myName); //arvind 9 | console.log(mathsMarks); //99 10 | } 11 | 12 | printMathsMarks(); 13 | -------------------------------------------------------------------------------- /02 Advance JS/07 Scopes/Codes/lexicalScope3.js: -------------------------------------------------------------------------------- 1 | var myName = "arvind"; 2 | 3 | function printMathsMarks() { 4 | console.log(myName); //arvind 5 | englishMarks = 98; //autoglobal ->js will make assign this variable global scope 6 | console.log(englishMarks); 7 | } 8 | //console.log(englishMarks); //throw an error 9 | printMathsMarks(); 10 | -------------------------------------------------------------------------------- /02 Advance JS/07 Scopes/Codes/var_demo.js: -------------------------------------------------------------------------------- 1 | var myName = "arvind"; 2 | 3 | function printName() { 4 | var userName = "arvind pandit"; 5 | console.log(myName); 6 | console.log(userName); 7 | } 8 | 9 | printName(); 10 | console.log(myName); 11 | console.log(userName); //throw error ? userName has a scope of printName function 12 | -------------------------------------------------------------------------------- /02 Advance JS/07 Scopes/Notes/Scope.md: -------------------------------------------------------------------------------- 1 | # Scopes in JavaScript 2 | 3 | In JavaScript, scope refers to the visibility and accessibility of variables and functions within a program. Scopes determine where variables and functions are available for use. JavaScript has three types of scopes: global scope, function scope, and block scope. 4 | 5 | ## Global Scope 6 | 7 | Variables declared outside any function or block have global scope. They are accessible from anywhere within the JavaScript file. 8 | 9 | Example: 10 | 11 | ```javascript 12 | var myName = "arvind"; // Global scope 13 | 14 | function printName() { 15 | console.log(myName); 16 | } 17 | 18 | printName(); // Output: arvind 19 | ``` 20 | 21 | In the above example, the variable `myName` is declared in the global scope and can be accessed from the `printName` function. 22 | 23 | ## Function Scope 24 | 25 | Variables declared within a function have function scope. They are only accessible within the function. 26 | 27 | Example: 28 | 29 | ```javascript 30 | function printName() { 31 | var myName = "arvind"; // Function scope 32 | console.log(myName); 33 | } 34 | 35 | printName(); // Output: arvind 36 | console.log(myName); // Error: myName is not defined 37 | ``` 38 | 39 | In the above example, the variable `myName` is declared within the `printName` function and can only be accessed from within that function. 40 | 41 | ## Block Scope 42 | 43 | Block scope was introduced in ECMAScript 6 (ES6) with the introduction of `let` and `const` declarations. Variables declared with `let` and `const` have block scope, which means they are only accessible within the block where they are defined. 44 | 45 | Example: 46 | 47 | ```javascript 48 | { 49 | var myName = "arvind"; // Block scope with var 50 | let age = 25; // Block scope with let 51 | const country = "USA"; // Block scope with const 52 | 53 | console.log(myName); // Output: arvind 54 | console.log(age); // Output: 25 55 | console.log(country); // Output: USA 56 | } 57 | 58 | console.log(myName); // Output: arvind 59 | console.log(age); // Error: age is not defined 60 | console.log(country); // Error: country is not defined 61 | ``` 62 | 63 | In the above example, the variable `myName` is declared with `var` and has block scope. However, `age` and `country` are declared with `let` and `const`, respectively, and have block scope as well. 64 | 65 | ## Variable Declarations: var, let, and const 66 | 67 | In JavaScript, variable declarations can be made using `var`, `let`, and `const` keywords, each with its own scoping rules. 68 | 69 | - `var`: Variables declared with `var` have function scope or global scope, depending on where they are declared. They are hoisted to the top of their scope during the parsing phase. 70 | 71 | - `let`: Variables declared with `let` have block scope. They are not hoisted and are only accessible within the block where they are defined. 72 | 73 | - `const`: Variables declared with `const` also have block scope like `let`. However, `const` variables are read-only and cannot be reassigned after declaration. 74 | 75 | It is recommended to use `let` and `const` for variable declarations to avoid common pitfalls associated with `var`. 76 | 77 | ## Variable Usage: Target vs Source 78 | 79 | In your JavaScript code, each variable can be used in one of two ways: as a target or as a source. 80 | 81 | - **Target Usage**: When a variable is used as a target, it means that a value is being assigned to that variable. 82 | 83 | Example: 84 | 85 | ```javascript 86 | x = 10; // x is a target variable 87 | ``` 88 | 89 | In the above example, the variable `x` is used as a target to assign the value `10` to it. 90 | 91 | - **Source Usage**: When a variable is used as a source, it means that the variable is being used to retrieve a value or as part of an expression. 92 | 93 | Example: 94 | 95 | ```javascript 96 | y = 10 + x; // x is a source variable 97 | console.log(x); // x is a source variable 98 | ``` 99 | 100 | In the above examples, the variable `x` is used as a source. It is either used to retrieve its value (`10 + x`) or printed to the console. 101 | 102 | ## Parsing Phase and Execution 103 | 104 | JavaScript follows a two-phase process when executing code: parsing and execution. 105 | 106 | During the parsing phase, JavaScript assigns scopes to variables and functions without executing the code. It looks for formal declarations and allocates scopes accordingly. However, it does not assign values to variables during this phase. 107 | 108 | During the execution phase, JavaScript reads and executes the code, utilizing the assigned scopes. Variables are assigned values and functions are executed. 109 | 110 | Example: 111 | 112 | ```javascript 113 | var myName = "arvind"; 114 | 115 | function printMathsMarks() { 116 | var mathsMarks = 99; 117 | console.log(myName); // Output: arvind 118 | console.log(mathsMarks); // Output: 99 119 | } 120 | 121 | printMathsMarks(); 122 | ``` 123 | 124 | In the above example, during the parsing phase, JavaScript assigns scopes to the variables `myName` and `mathsMarks`. In the execution phase, the code is executed, and the assigned values are accessed and printed. 125 | 126 | ## Lexical Scope 127 | 128 | Lexical scope refers to the scope resolution based on the placement of variables and functions in the source code. In JavaScript, lexical scope is determined at the time of code compilation and remains static during runtime. It means that a variable or function can access variables and functions in its outer scope. 129 | 130 | Example: 131 | 132 | ```javascript 133 | function outerFunction() { 134 | var outerVariable = "I'm from outer function"; 135 | 136 | function innerFunction() { 137 | var innerVariable = "I'm from inner function"; 138 | console.log(outerVariable); // Output: I'm from outer function 139 | console.log(innerVariable); // Output: I'm from inner function 140 | } 141 | 142 | innerFunction(); 143 | } 144 | 145 | outerFunction(); 146 | ``` 147 | 148 | In the above example, the variable `outerVariable` defined in the outer function is accessible within the inner function due to lexical scoping. 149 | 150 | ## Autoglobals 151 | 152 | Autoglobals refer to variables that are automatically considered in the global scope if they are not found in any outer scope during the execution phase. This happens when a variable is used as a target reference (assignment) rather than a source reference (value retrieval). 153 | 154 | Example: 155 | 156 | ```javascript 157 | function printMathsMarks() { 158 | console.log(myName); // Output: arvind 159 | englishMarks = 98; // Autoglobal: JavaScript assigns it to the global scope 160 | console.log(englishMarks); // Output: 98 161 | } 162 | 163 | printMathsMarks(); 164 | console.log(englishMarks); // Output: 98 165 | ``` 166 | 167 | In the above example, the variable `englishMarks` is not declared within the function. However, when it is assigned a value (`englishMarks = 98`), JavaScript automatically considers it as a global variable and assigns it to the global scope. 168 | 169 | ## Conclusion 170 | 171 | Understanding scopes in JavaScript is crucial for writing efficient and bug-free code. Scopes define the visibility and accessibility of variables and functions, ensuring that they are used appropriately within the program. By grasping the concepts of global scope, function scope, block scope, lexical scope, and autoglobals, developers can write better JavaScript code and avoid common pitfalls. 172 | 173 | --- 174 | -------------------------------------------------------------------------------- /02 Advance JS/08 Scopes 2/Codes/autoGlobal.js: -------------------------------------------------------------------------------- 1 | function printName() { 2 | // console.log(myName); // throw an error 3 | myName = "arvind"; //autoglobal 4 | console.log(myName); 5 | } 6 | 7 | printName(); 8 | -------------------------------------------------------------------------------- /02 Advance JS/08 Scopes 2/Codes/autoglobal2.js: -------------------------------------------------------------------------------- 1 | myName = "arvind"; //autoglobal 2 | function printName() { 3 | console.log(myName); 4 | } 5 | 6 | printName(); 7 | -------------------------------------------------------------------------------- /02 Advance JS/08 Scopes 2/Codes/autoglobal3.js: -------------------------------------------------------------------------------- 1 | x = 10; 2 | 3 | function fun() { 4 | //scope of function fun 5 | //var x = 20; 6 | x = 20; 7 | console.log(x); //20 8 | } 9 | console.log(x); //10 10 | fun(); 11 | console.log(x); //20 12 | -------------------------------------------------------------------------------- /02 Advance JS/08 Scopes 2/Codes/example.js: -------------------------------------------------------------------------------- 1 | // var x = 20; 2 | // y = 30; 3 | // sum(x, y); 4 | // function sum(x, y) { 5 | // console.log(x + y); //reference error 6 | // } 7 | 8 | var x = 20; 9 | y = 30; 10 | 11 | function sum(x, y) { 12 | console.log(x + y); 13 | 50; 14 | } 15 | 16 | sum(x, y); 17 | -------------------------------------------------------------------------------- /02 Advance JS/08 Scopes 2/Codes/hoisting.js: -------------------------------------------------------------------------------- 1 | fun(); 2 | 3 | function fun() { 4 | var doFun = "let's do fun"; 5 | console.log(doFun); 6 | } 7 | 8 | /** 9 | * phase 1: function fun -> global scope 10 | * doFun -> scope of function fun 11 | * 12 | * phase 2: execution phase 13 | * 14 | */ 15 | -------------------------------------------------------------------------------- /02 Advance JS/08 Scopes 2/Codes/strict_mode.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | function fun() { 4 | x = "arvind"; 5 | console.log(x); //throw an error - x is not defined 6 | } 7 | 8 | fun(); 9 | -------------------------------------------------------------------------------- /02 Advance JS/08 Scopes 2/Codes/undeclared.js: -------------------------------------------------------------------------------- 1 | console.log(myName); //error - Cannot access 'myName' before initialization 2 | let myName = "arvind"; 3 | /** 4 | * let is a block scoped variable 5 | * so we cannot use it before initializing 6 | * 7 | */ 8 | console.log(myName); //arvind 9 | -------------------------------------------------------------------------------- /02 Advance JS/08 Scopes 2/Codes/undefined.js: -------------------------------------------------------------------------------- 1 | console.log(myName); //undefined 2 | var myName = "arvind"; 3 | console.log(myName); //arvind 4 | -------------------------------------------------------------------------------- /02 Advance JS/08 Scopes 2/Notes/scopes2.md: -------------------------------------------------------------------------------- 1 | # Scopes 2 2 | 3 | In JavaScript, scopes play a crucial role in determining the visibility and accessibility of variables within a program. This README file explores various concepts related to scopes and their behaviors. 4 | 5 | ## Undefined and Undeclared Variables 6 | 7 | **Undefined** refers to the variable state when it exists in the scope, but during the execution phase, it has not been assigned a value yet. 8 | 9 | Example: 10 | 11 | ```javascript 12 | console.log(myName); // undefined 13 | var myName = "arvind"; 14 | console.log(myName); // arvind 15 | ``` 16 | 17 | In the above example, `myName` is initially `undefined` as it exists in the scope but has not been assigned a value. Later, it is assigned the value `"arvind"`, resulting in `arvind` being printed. 18 | 19 | **Undeclared** refers to the variable state when a variable is used before it is formally declared or assigned a value. It typically leads to an error. 20 | 21 | Example: 22 | 23 | ```javascript 24 | console.log(myName); // Error: Cannot access 'myName' before initialization 25 | let myName = "arvind"; 26 | console.log(myName); // arvind 27 | ``` 28 | 29 | In the above example, `myName` is used before it is formally declared, resulting in an error. Once declared and assigned a value, it can be accessed without issues. 30 | 31 | ## Autoglobals 32 | 33 | Autoglobals are variables that are automatically considered to have global scope when they are used in a scope where they are not declared. 34 | 35 | Example 1: 36 | 37 | ```javascript 38 | function printName() { 39 | myName = "arvind"; // autoglobal 40 | console.log(myName); 41 | } 42 | 43 | printName(); 44 | ``` 45 | 46 | In the above example, `myName` is not declared within the `printName` function, but it is used as a target (assigned a value). JavaScript automatically considers it as a global variable, and its value is printed successfully. 47 | 48 | Example 2: 49 | 50 | ```javascript 51 | myName = "arvind"; // autoglobal 52 | function printName() { 53 | console.log(myName); 54 | } 55 | 56 | printName(); 57 | ``` 58 | 59 | In this example, `myName` is assigned a value outside any function, making it a global variable. It can be accessed within the `printName` function and its value is printed successfully. 60 | 61 | ## Strict Mode 62 | 63 | Strict mode is a feature in JavaScript that enforces stricter rules and helps in writing cleaner and more reliable code. It enables a safer subset of JavaScript, preventing the use of certain error-prone practices. 64 | 65 | Example: 66 | 67 | ```javascript 68 | "use strict"; 69 | 70 | function fun() { 71 | x = "arvind"; // Error: x is not defined 72 | console.log(x); 73 | } 74 | 75 | fun(); 76 | ``` 77 | 78 | In the above example, the `"use strict"` directive enables strict mode. The code attempts to assign a value to an undeclared variable `x`, leading to an error. Strict mode helps in identifying such issues and promotes better coding practices. 79 | 80 | ## Hoisting 81 | 82 | Hoisting is a behavior in JavaScript where function and variable declarations are moved to the top of their containing scope during the compilation phase. This allows us to access functions and variables before they are formally declared. 83 | 84 | Example: 85 | 86 | ```javascript 87 | fun(); 88 | 89 | function fun() { 90 | var doFun = "let's do fun"; 91 | console.log(doFun); 92 | } 93 | ``` 94 | 95 | In the above example, the function `fun()` is called before its formal declaration. However, due to hoisting, the function is moved to the top during the parsing phase, allowing it to be invoked successfully. 96 | 97 | ## Conclusion 98 | 99 | Scopes in JavaScript govern the visibility and accessibility of variables. Understanding the concepts of undefined and undeclared variables, autoglobals, strict mode, and hoisting is essential for writing reliable and maintainable code. By mastering these concepts, you can effectively manage variables and their scope within your JavaScript programs. 100 | -------------------------------------------------------------------------------- /02 Advance JS/09 Function Expression/Codes/anonymous_function.js: -------------------------------------------------------------------------------- 1 | var hello = function () { 2 | //anonymous function -> no name 3 | //hard to debug 4 | console.log("hello"); 5 | }; 6 | 7 | var hello2 = function namedFunction() { 8 | console.log("named function"); 9 | }; 10 | 11 | hello(); 12 | hello2(); 13 | -------------------------------------------------------------------------------- /02 Advance JS/09 Function Expression/Codes/functionExpression.js: -------------------------------------------------------------------------------- 1 | //function expression 2 | 3 | //here the first keyword in the line is not function , it is var 4 | var printName = function printing() { 5 | //function expression 6 | console.log("hello, arvind"); 7 | }; 8 | 9 | //here the first keyword in the line is function 10 | function fun() { 11 | //function definition 12 | console.log("inside fun"); 13 | } 14 | 15 | //here also the first keyword is not function, it is "(" 16 | (function () { 17 | console.log("function expression"); 18 | }); 19 | -------------------------------------------------------------------------------- /02 Advance JS/09 Function Expression/Codes/passingFunction.js: -------------------------------------------------------------------------------- 1 | function first(fn) { 2 | console.log("inside first function"); 3 | fn(); 4 | } 5 | 6 | function second() { 7 | console.log("inside second function"); 8 | } 9 | 10 | first(second); 11 | -------------------------------------------------------------------------------- /02 Advance JS/09 Function Expression/Codes/scope_of_fn_expression.js: -------------------------------------------------------------------------------- 1 | var x = function anonyMous() { 2 | console.log( 3 | "the scope of this anonymous function is inside the scope of the x" 4 | ); 5 | }; 6 | 7 | x(); 8 | //anonyMous(); //throw an error -anonyMous is not defined 9 | console.log(typeof x); //function 10 | 11 | console.log(typeof x()); //undefined 12 | /** 13 | * if nothing is returned from a function 14 | * then it returns "undefined" by default 15 | */ 16 | 17 | var y = function () { 18 | return 7; 19 | }; 20 | 21 | console.log(typeof y); //function 22 | console.log(typeof y()); //number because we're returning number 7; 23 | 24 | var z = function () { 25 | return "arvind"; 26 | }; 27 | 28 | console.log(z()); //string because we're returing string "arvind" 29 | -------------------------------------------------------------------------------- /02 Advance JS/09 Function Expression/Notes/function_expression.md: -------------------------------------------------------------------------------- 1 | # Function Expressions 2 | 3 | Function expressions are a way to define functions in JavaScript. They provide flexibility in creating and using functions within your code. This README file explores the concept of function expressions and their characteristics. 4 | 5 | ## Function Expression vs. Function Definition 6 | 7 | **Function Expression**: A function expression is created by assigning a function to a variable. The variable then becomes a reference to the function. 8 | 9 | **Function Definition**: A function definition, also known as a function declaration, is created using the `function` keyword followed by the function name. 10 | 11 | ```javascript 12 | // Function Expression 13 | var printName = function printing() { 14 | console.log("hello, arvind"); 15 | }; 16 | 17 | // Function Definition 18 | function fun() { 19 | console.log("inside fun"); 20 | } 21 | ``` 22 | 23 | In the above example, `printName` is a function expression, as it is assigned to a variable using the `function` keyword. `fun` is a function definition, as it uses the `function` keyword directly. 24 | 25 | Function expressions offer more flexibility as they can be used as values, passed as arguments to other functions, or assigned dynamically. Function definitions, on the other hand, are hoisted and can be accessed anywhere within their scope. 26 | 27 | ## Types of Function Expressions 28 | 29 | There are two types of function expressions: 30 | 31 | 1. **Anonymous Function**: An anonymous function is a function without a name. It is commonly used when the function is used only once or as a callback function. 32 | 33 | 2. **Named Function**: A named function expression has a name assigned to it. It aids in better stack traces and self-reference within the function body. 34 | 35 | ```javascript 36 | var hello = function () { 37 | console.log("hello"); 38 | }; 39 | 40 | var hello2 = function namedFunction() { 41 | console.log("named function"); 42 | }; 43 | 44 | hello(); 45 | hello2(); 46 | ``` 47 | 48 | In the above example, `hello` is an anonymous function, as it does not have a name. `hello2` is a named function, as it is assigned a name `namedFunction`. 49 | 50 | Note: Anonymous functions can be harder to debug, and recursion within them can be trickier due to the absence of a named reference. 51 | 52 | ## Scope of Function Expressions 53 | 54 | The scope of a function expression depends on where it is defined and assigned. It follows the scope rules of variables in JavaScript. 55 | 56 | ```javascript 57 | var x = function anonyMous() { 58 | console.log( 59 | "the scope of this anonymous function is inside the scope of the x" 60 | ); 61 | }; 62 | 63 | x(); 64 | //anonyMous(); //throw an error -anonyMous is not defined 65 | console.log(typeof x); //function 66 | 67 | console.log(typeof x()); //undefined 68 | /** 69 | * if nothing is returned from a function 70 | * then it returns "undefined" by default 71 | */ 72 | 73 | var y = function () { 74 | return 7; 75 | }; 76 | 77 | console.log(typeof y); //function 78 | console.log(typeof y()); //number because we're returning number 7; 79 | 80 | var z = function () { 81 | return "arvind"; 82 | }; 83 | 84 | console.log(z()); //string because we're returning string "arvind" 85 | ``` 86 | 87 | This code example demonstrates the usage of function expressions. `x` is a function expression with the name `anonyMous`. It is called using `x()`, and the scope of the function is within the scope of the `x` variable. The code also shows the difference in `typeof` for the function itself (`typeof x`) and the result of calling the function (`typeof x()`). Additionally, the example includes `y`, a function expression that returns a number, and `z`, a function expression that returns a string. 88 | 89 | ## Conclusion 90 | 91 | Function expressions provide a flexible way to define functions in JavaScript. They can be assigned to variables, used as values, and passed as arguments to other functions. Understanding the differences between function expressions and function definitions, as well as the scope of function expressions, is crucial for effective JavaScript programming. 92 | -------------------------------------------------------------------------------- /02 Advance JS/10 Closures and Intro to Callbacks/Codes/array_map_function.js: -------------------------------------------------------------------------------- 1 | var arr = [1, 2, 3, 4, 5]; 2 | 3 | var newArr = arr.map(function (element, index) { 4 | console.log(element, index); 5 | return element * element; 6 | }); 7 | 8 | console.log(newArr, arr); 9 | 10 | var students = arr.map(function (element) { 11 | return "student" + element; 12 | }); 13 | 14 | console.log(students); 15 | -------------------------------------------------------------------------------- /02 Advance JS/10 Closures and Intro to Callbacks/Codes/callback_demo.js: -------------------------------------------------------------------------------- 1 | function arvind(fn) { 2 | //fn is a callback function -> function passed inside other function 3 | console.log("arvind"); 4 | fn(); 5 | } 6 | 7 | function pandit() { 8 | console.log("pandit"); 9 | } 10 | 11 | arvind(pandit); 12 | -------------------------------------------------------------------------------- /02 Advance JS/10 Closures and Intro to Callbacks/Codes/setInterval2.js: -------------------------------------------------------------------------------- 1 | var interval = setInterval(function () { 2 | console.log("hello arvind"); 3 | }, 1000); 4 | 5 | setTimeout(function () { 6 | clearInterval(interval); 7 | }, 8000); 8 | -------------------------------------------------------------------------------- /02 Advance JS/10 Closures and Intro to Callbacks/Codes/setInterval_demo.js: -------------------------------------------------------------------------------- 1 | //setInterval perform a task again and again after given interval of time 2 | setInterval(function () { 3 | console.log("hello! arvind"); 4 | }, 1000); 5 | -------------------------------------------------------------------------------- /02 Advance JS/10 Closures and Intro to Callbacks/Codes/setTimeout_demo.js: -------------------------------------------------------------------------------- 1 | //setTimeout is a function which is performed after a given interval of time 2 | 3 | setTimeout(function () { 4 | console.log("arvind"); 5 | }, 2000); 6 | 7 | setTimeout(function () { 8 | console.log("pandit"); 9 | }, 3000); 10 | -------------------------------------------------------------------------------- /02 Advance JS/10 Closures and Intro to Callbacks/Notes/closure.md: -------------------------------------------------------------------------------- 1 | # Closures and Intro to Callbacks 2 | 3 | This README.md file provides an overview of closures and their relation to special functions like `setTimeout`, `setInterval`, and `.map()`. Understanding closures requires familiarity with these functions and concepts. Let's dive into each of them. 4 | 5 | ## setTimeout 6 | 7 | `setTimeout` is a function that allows us to execute a task once after a specific time interval. 8 | 9 | **Code Example:** 10 | 11 | ```javascript 12 | // setTimeout is a function performed after a given interval of time 13 | 14 | setTimeout(function () { 15 | console.log("arvind"); 16 | }, 2000); 17 | 18 | setTimeout(function () { 19 | console.log("pandit"); 20 | }, 3000); 21 | ``` 22 | 23 | ## setInterval 24 | 25 | `setInterval` is a function that enables the execution of a task repeatedly after a specified time interval. 26 | 27 | **Code Example:** 28 | 29 | ```javascript 30 | // setInterval performs a task repeatedly after a given interval of time 31 | 32 | setInterval(function () { 33 | console.log("hello! arvind"); 34 | }, 1000); 35 | ``` 36 | 37 | ## Callback Function 38 | 39 | A callback function is a function that is passed as an argument to another function. In mathematical terms, it can be seen as `f(g(x))`, where `g(x)` is the callback function passed inside function `f`. 40 | 41 | Let's consider an example to understand callbacks: 42 | 43 | ```javascript 44 | function arvind(fn) { 45 | // fn is a callback function -> function passed inside another function 46 | console.log("arvind"); 47 | fn(); 48 | } 49 | 50 | function pandit() { 51 | console.log("pandit"); 52 | } 53 | 54 | arvind(pandit); 55 | ``` 56 | 57 | In the above code, `pandit` is a callback function passed as an argument to the `arvind` function. 58 | 59 | Note: Both `setTimeout` and `setInterval` accept callbacks as arguments. 60 | 61 | ## The .map() Function 62 | 63 | The `.map()` function is another function that takes a callback. It is used to transform elements in an array and return a new array with the modified values. 64 | 65 | **Code Example:** 66 | 67 | ```javascript 68 | var arr = [1, 2, 3, 4, 5]; 69 | 70 | var newArr = arr.map(function (element, index) { 71 | console.log(element, index); 72 | return element * element; 73 | }); 74 | 75 | console.log(newArr, arr); 76 | 77 | var students = arr.map(function (element) { 78 | return "student" + element; 79 | }); 80 | 81 | console.log(students); 82 | ``` 83 | 84 | In the above code, we use the `.map()` function to square each element of the `arr` array and create a new array `newArr`. We also demonstrate how to append "student" to each element of the `arr` array using the `.map()` function. 85 | 86 | ## Conclusion 87 | 88 | In this README, we introduced the concept of closures and their relationship with special functions like `setTimeout`, `setInterval`, and `.map()`. Closures play a vital role in JavaScript and will be explored further in the next lesson. 89 | -------------------------------------------------------------------------------- /02 Advance JS/11 Promises and callbacks/Codes/closure_demo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Closure- function remembers its lexical scope 3 | * even when it is executed outside 4 | * 5 | */ 6 | 7 | function printName(lastName) { 8 | setTimeout(function () { 9 | console.log(`arvind ${lastName}`); 10 | }, 5000); 11 | console.log("function printName is ended"); 12 | } 13 | 14 | console.log("first statement"); 15 | printName("pandit"); 16 | console.log("last statement"); 17 | -------------------------------------------------------------------------------- /02 Advance JS/11 Promises and callbacks/Codes/closure_demo2.js: -------------------------------------------------------------------------------- 1 | function printName(lastName) { 2 | setTimeout(function () { 3 | console.log(`arvind ${lastName}`); 4 | }, 5000); 5 | console.log("function printName is ended"); 6 | lastName = "pandit prajapati"; 7 | } 8 | 9 | console.log("first statement"); 10 | printName("pandit"); 11 | console.log("last statement"); 12 | -------------------------------------------------------------------------------- /02 Advance JS/11 Promises and callbacks/Codes/closure_demo3.js: -------------------------------------------------------------------------------- 1 | function printName(name) { 2 | console.log(`name is printed inside printName ${name}`); 3 | return function printingName() { 4 | console.log(`name is printed inside printingName ${name}`); 5 | }; 6 | } 7 | 8 | var newName = printName("arvind"); 9 | newName(); 10 | /** 11 | * newName is accessing the name function outside the printName 12 | * this is due to the closure 13 | * and remembers the variable name even executed outside the printName 14 | */ 15 | -------------------------------------------------------------------------------- /02 Advance JS/11 Promises and callbacks/Codes/closure_demo4.js: -------------------------------------------------------------------------------- 1 | function test() { 2 | for (var i = 0; i < 3; i++) { 3 | setTimeout(function exec() { 4 | console.log(`i : ${i}`); // 'i: ' + i 5 | }, i * 1000); 6 | } 7 | } 8 | 9 | test(); 10 | -------------------------------------------------------------------------------- /02 Advance JS/11 Promises and callbacks/Codes/closure_demo5.js: -------------------------------------------------------------------------------- 1 | function test() { 2 | for (let i = 0; i < 3; i++) { 3 | setTimeout(function exec() { 4 | console.log(`i : ${i}`); // 'i: ' + i 5 | }, i * 1000); 6 | } 7 | } 8 | 9 | test(); 10 | -------------------------------------------------------------------------------- /02 Advance JS/11 Promises and callbacks/Notes/closures2-promise.md: -------------------------------------------------------------------------------- 1 | # Promises and Callbacks 2 | 3 | This README file provides an overview of closures and their role in JavaScript. We will explore various examples to understand how closures work and their significance. 4 | 5 | ## Example: Using `setTimeout` and Closures 6 | 7 | Let's start with an example that demonstrates the concept of closures with the `setTimeout` function. 8 | 9 | ```javascript 10 | function printName(lastName) { 11 | setTimeout(function writeName() { 12 | console.log(`arvind ${lastName}`); 13 | }, 5000); 14 | console.log("function printName is ended"); 15 | } 16 | 17 | console.log("first statement"); 18 | printName("pandit"); 19 | console.log("last statement"); 20 | ``` 21 | 22 | In this code snippet, the `printName` function is called and passed the argument `"pandit"`. However, the `setTimeout` callback function `writeName` is executed after a delay of 5000 milliseconds. Surprisingly, even though the `printName` function has already ended, `writeName` is still able to access the `lastName` variable. This behavior is possible due to closures. 23 | 24 | ## Closure 25 | 26 | A closure is when a function "remembers" its lexical scope, even when it is executed outside that lexical scope. 27 | 28 | **Example 1:** 29 | 30 | ```javascript 31 | function printName(lastName) { 32 | setTimeout(function () { 33 | console.log(`arvind ${lastName}`); 34 | }, 5000); 35 | console.log("function printName is ended"); 36 | lastName = "pandit prajapati"; 37 | } 38 | 39 | console.log("first statement"); 40 | printName("pandit"); 41 | console.log("last statement"); 42 | ``` 43 | 44 | In this example, even though the value of `lastName` is modified inside the `printName` function after the `setTimeout` is defined, the closure allows the `writeName` function to access the updated value when it is eventually executed. 45 | 46 | **Example 2:** 47 | 48 | ```javascript 49 | function printName(name) { 50 | console.log(`name is printed inside printName ${name}`); 51 | return function printingName() { 52 | console.log(`name is printed inside printingName ${name}`); 53 | }; 54 | } 55 | 56 | var newName = printName("arvind"); 57 | newName(); 58 | ``` 59 | 60 | Here, the `printingName` function is returned from the `printName` function and assigned to the variable `newName`. Even when executed outside the lexical scope of `printName`, `newName` can still access the `name` variable due to closures. 61 | 62 | **Example 3:** 63 | 64 | ```javascript 65 | function test() { 66 | for (var i = 0; i < 3; i++) { 67 | setTimeout(function exec() { 68 | console.log(`i: ${i}`); 69 | }, i * 1000); 70 | } 71 | } 72 | 73 | test(); 74 | ``` 75 | 76 | In this example, the `setTimeout` callback function `exec` is executed after a certain time interval. However, the variable `i` is shared among the different callback functions created in each iteration of the loop. As a result, when the callbacks are finally executed, they all access the same value of `i`, which is the last value from the loop (i.e., `3`), due to closures. 77 | 78 | **Example 4:** 79 | 80 | ```javascript 81 | function test() { 82 | for (let i = 0; i < 3; i++) { 83 | setTimeout(function exec() { 84 | console.log(`i: ${i}`); 85 | }, i * 1000); 86 | } 87 | } 88 | 89 | test(); 90 | ``` 91 | 92 | In this modified example, the `let` keyword is used to declare the loop variable `i`. Using `let` creates a new block scope for each iteration of the loop. As a result, each callback function created by `setTimeout` has its own separate copy of `i`, leading to the expected output. 93 | 94 | ## Conclusion 95 | 96 | Closures are a powerful feature in JavaScript that allow functions to retain access to variables from their lexical scope, even when executed outside that scope. Understanding closures is essential for working with asynchronous code, callbacks, and other advanced JavaScript concepts. 97 | -------------------------------------------------------------------------------- /02 Advance JS/12 Async Nature of JS/Codes/demo.js: -------------------------------------------------------------------------------- 1 | function print() { 2 | console.log("print line 1"); 3 | setTimeout(function timeout() { 4 | console.log("inside the timeout function"); 5 | }, 3000); 6 | console.log("print line 2"); 7 | } 8 | 9 | print(); 10 | -------------------------------------------------------------------------------- /02 Advance JS/12 Async Nature of JS/Codes/demo2.js: -------------------------------------------------------------------------------- 1 | function demo() { 2 | console.log("first"); 3 | 4 | setTimeout(function fun() { 5 | console.log("inside function fun"); 6 | }, 2000); 7 | 8 | for (var i = 0; i < 1000000000; i++) { 9 | //some time consuming task 10 | } 11 | 12 | setTimeout(function gun() { 13 | console.log("inside function gun"); 14 | }, 0); 15 | 16 | console.log("last"); 17 | } 18 | 19 | demo(); 20 | -------------------------------------------------------------------------------- /02 Advance JS/12 Async Nature of JS/Codes/demo3.js: -------------------------------------------------------------------------------- 1 | function first(fn) { 2 | console.log("first"); 3 | var x = 10; 4 | setTimeout(function () { 5 | console.log("setTimeout is done"); 6 | fn(x); 7 | }, 4000); 8 | } 9 | 10 | function printAge(age) { 11 | console.log("my age is ", age); 12 | } 13 | 14 | first(printAge); 15 | -------------------------------------------------------------------------------- /02 Advance JS/12 Async Nature of JS/Codes/whyIsThisHappening.js: -------------------------------------------------------------------------------- 1 | console.log("hello arvind"); 2 | 3 | function fun() { 4 | setTimeout(function () { 5 | console.log("setTimeout"); 6 | }, 0); 7 | } 8 | fun(); 9 | console.log("hello arvind 2"); 10 | -------------------------------------------------------------------------------- /03 Async JS/13 Promises/Codes/callback_hell.js: -------------------------------------------------------------------------------- 1 | // Tasks: 2 | // 1. Write a function to download data from a url 3 | // 2. Write a function to save that downloaded data in a file and return the filename 4 | // 3. Write a function to upload the file written in previous step to a newurl 5 | 6 | function downloadData(url, fn) { 7 | console.log("downloading started"); 8 | 9 | setTimeout(function () { 10 | var data = "ARVIND DATA"; 11 | console.log(data, "downloaded successfully from", url); 12 | fn(data); 13 | }, 4000); 14 | } 15 | 16 | function saveFile(file, fn) { 17 | console.log("saving file started"); 18 | setTimeout(function () { 19 | let newFile = "arvind.txt"; 20 | console.log( 21 | file, 22 | "saved successfully on the local device in the filename", 23 | newFile 24 | ); 25 | fn(newFile); 26 | }, 2000); 27 | } 28 | 29 | function uploadFile(file, newUrl) { 30 | console.log("uploading started"); 31 | setTimeout(function () { 32 | //writing logic 33 | console.log(file, "file uploaded successfully", newUrl); 34 | }, 5000); 35 | } 36 | 37 | downloadData("www.arvindPandit.com", function download(data) { 38 | saveFile(data, function writeFile(file) { 39 | uploadFile(file, "www.arvindPanditNew.com"); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /03 Async JS/13 Promises/Codes/callback_inversion_of_control.js: -------------------------------------------------------------------------------- 1 | function internalFn(name, fn) { 2 | console.log(name); 3 | console.log("calling the callback function"); 4 | //this internalFn can call the callback once , twice or none 5 | //we'll never know 6 | //at calling site , we don't have this control 7 | // this is known as inversion of control 8 | // this is a major drawback of callback 9 | // to resolve this, js introducted promises 10 | fn(); 11 | console.log("funtion is called once"); 12 | fn(); 13 | } 14 | 15 | internalFn("arvind", function () { 16 | for (let i = 0; i < 10; i++) { 17 | console.log(i, i * i); 18 | } 19 | }); 20 | -------------------------------------------------------------------------------- /03 Async JS/13 Promises/Codes/download_callback.js: -------------------------------------------------------------------------------- 1 | function downloadData(url, fn) { 2 | console.log("downloading started"); 3 | 4 | setTimeout(function () { 5 | var data = "ARVIND DATA"; 6 | console.log(data, "downloaded successfully from", url); 7 | fn(data); 8 | }, 4000); 9 | } 10 | 11 | var x = downloadData("www.arvindPandit.com", function (data) { 12 | console.log(data); 13 | return data; 14 | }); 15 | -------------------------------------------------------------------------------- /03 Async JS/13 Promises/Codes/promise_demo1.js: -------------------------------------------------------------------------------- 1 | function toDoTask() { 2 | return new Promise(function (resolve, reject) { 3 | console.log("inside promise"); 4 | resolve("promise resolved"); 5 | }); 6 | } 7 | 8 | toDoTask(); 9 | -------------------------------------------------------------------------------- /03 Async JS/13 Promises/Codes/promise_demo2.js: -------------------------------------------------------------------------------- 1 | function promiseDemo() { 2 | return new Promise(function (resolve, reject) { 3 | console.log("inside the promise"); 4 | setTimeout(function timer() { 5 | console.log("inside the timer callback"); 6 | resolve("promise resolved"); 7 | }, 4000); 8 | }); 9 | } 10 | 11 | promiseDemo(); 12 | -------------------------------------------------------------------------------- /03 Async JS/13 Promises/Codes/promise_demo3.js: -------------------------------------------------------------------------------- 1 | function promiseDemo() { 2 | return new Promise(function (resolve, reject) { 3 | console.log("inside the promise"); 4 | setTimeout(function timer() { 5 | console.log("inside the timer callback"); 6 | reject("promise rejected"); 7 | }, 4000); 8 | }); 9 | } 10 | 11 | promiseDemo(); 12 | -------------------------------------------------------------------------------- /03 Async JS/14 Promises Continued/Codes/feature.js: -------------------------------------------------------------------------------- 1 | // Tasks: 2 | // 1. Write a function to download data from a url 3 | // 2. Write a function to save that downloaded data in a file and return the filename 4 | // 3. Write a function to upload the file written in previous step to a newurl 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🚀 JavaScript Learning Repository 2 | 3 | 👋 Welcome to the JavaScript Learning Repository! I'm Arvind Pandit, and this is where I share my knowledge and expertise in JavaScript. This repository contains comprehensive learning materials and code examples for JavaScript, catering to beginners and experienced developers alike. I'm passionate about JavaScript and excited to contribute to the community's learning journey through this repository. 4 | 5 | ## Table of Contents 6 | 7 | 1. Introduction to JavaScript 8 | 2. Advanced JavaScript 9 | 3. Async JavaScript 10 | 11 | ## Introduction to JavaScript 🌟 12 | 13 | In this section, I provide a solid introduction to JavaScript and cover the following topics: 14 | 15 | - [Introduction to JavaScript](https://github.com/arvindpndit/JavaScript/blob/master/01%20Intro%20to%20JS/01%20Intro%20to%20JS/Notes/intro-to-js-notes.md) 📚 16 | - [Introduction to JavaScript - 2](https://github.com/arvindpndit/JavaScript/blob/master/01%20Intro%20to%20JS/02%20Intro%20to%20JS-2/Notes/intro-to-js-notes-2.md) 🚀 17 | - [Introduction to Coercion](https://github.com/arvindpndit/JavaScript/tree/master/01%20Intro%20to%20JS/03%20Coercion/Notes) 🎯 18 | 19 | ## Advanced JavaScript 🔥 20 | 21 | The Advanced JavaScript section delves deeper into JavaScript concepts and covers the following topics: 22 | 23 | - [Coercion - Revision](https://github.com/arvindpndit/JavaScript/tree/master/01%20Intro%20to%20JS/03%20Coercion/Notes) 🔁 24 | - [Coercion - ToBoolean and Equality Operators](https://github.com/arvindpndit/JavaScript/blob/master/02%20Advance%20JS/05%20ToBoolean%20%26%20Strict%20Equality/Notes/ToBoolean_strict_operator.md) ✅ 25 | - [Abstract equality, NaN, and Special Types](https://github.com/arvindpndit/JavaScript/blob/master/02%20Advance%20JS/06%20Abstract%20equality%2C%20NaN%2C%20Special%20Types/Notes/Abstract_operator_NaN.md) ❓ 26 | - [Scopes](https://github.com/arvindpndit/JavaScript/blob/master/02%20Advance%20JS/07%20Scopes/Notes/Scope.md) 🌐 27 | - [Scopes 2](https://github.com/arvindpndit/JavaScript/blob/master/02%20Advance%20JS/08%20Scopes%202/Notes/scopes2.md) 🌍 28 | - [Function Expressions](https://github.com/arvindpndit/JavaScript/blob/master/02%20Advance%20JS/09%20Function%20Expression/Notes/function_expression.md) 💡 29 | - [Closures And Intro to Callbacks](https://github.com/arvindpndit/JavaScript/blob/master/02%20Advance%20JS/10%20Closures%20and%20Intro%20to%20Callbacks/Notes/closure.md) 🧩 30 | - [Promises And Callbacks](https://github.com/arvindpndit/JavaScript/blob/master/02%20Advance%20JS/11%20Promises%20and%20callbacks/Notes/closures2-promise.md) ⚡ 31 | - Async Nature of JS ⏰ 32 | 33 | ## Async JavaScript ⚡ 34 | 35 | The Async JavaScript section focuses on asynchronous programming in JavaScript and covers the following topics: 36 | 37 | - Promises 🤝 38 | - Promises Continued ➕ 39 | - Async Await 🚦 40 | - Async Await Cont. 🔄 41 | 42 | ## Usage 🚀 43 | 44 | Each topic in the repository contains its own set of code examples, explanations, and notes to help you learn JavaScript effectively. Feel free to explore the topics based on your learning needs and interests. Happy coding! 💻 45 | 46 | ## Contact Me ✉️ 47 | 48 | If you have any questions, suggestions, or just want to connect, you can reach out to me on [LinkedIn](https://www.linkedin.com/in/arvindpndit/). I would love to hear from you and engage in discussions related to JavaScript and programming. 49 | 50 | ## Contributing 🤝 51 | 52 | If you find any issues or have suggestions for improvement, please feel free to contribute. You can submit a pull request with your changes, and they will be reviewed and merged if appropriate. 53 | 54 | If you have any questions or need further assistance, please don't hesitate to reach out. Happy coding! 😊 55 | --------------------------------------------------------------------------------