-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
308 lines (260 loc) · 9.46 KB
/
index.js
File metadata and controls
308 lines (260 loc) · 9.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
// ========================================
// JavaScript-Specific Concepts
// ========================================
// 1. HOISTING - Variables and functions are hoisted to the top
// Variables declared with 'var' are hoisted and initialized as undefined
console.log(hoistedVar); // undefined (not an error!)
var hoistedVar = 5;
// Functions are fully hoisted
console.log(hoistedFunction()); // Works! Returns "Hello"
function hoistedFunction() {
return "Hello";
}
// 2. CLOSURE - Functions have access to outer function's variables
function outerFunction(x) {
return function innerFunction(y) {
return x + y; // innerFunction "closes over" x
};
}
const add5 = outerFunction(5);
console.log(add5(10)); // 15
// 3. PROTOTYPE-BASED INHERITANCE (not class-based like Java/Python)
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function () {
return this.name + " makes a sound";
};
const dog = new Animal("Dog");
console.log(dog.speak()); // Dog makes a sound
// 4. THIS BINDING - Context matters in JavaScript
const person = {
name: "Alice",
greet: function () {
return "Hello, " + this.name;
},
delayedGreet: function () {
setTimeout(function () {
// 'this' is undefined in regular function (or window in browser)
console.log(this.name); // undefined
}, 1000);
},
delayedGreetArrow: function () {
// Arrow function preserves 'this' from outer scope
setTimeout(() => {
console.log(this.name); // Alice
}, 1000);
},
};
// 5. CALLBACK FUNCTIONS - JavaScript's async pattern
function fetchData(callback) {
setTimeout(() => {
callback({ data: "Important Info" });
}, 1000);
}
fetchData((response) => {
console.log(response.data);
});
// 6. PROMISES - Better async handling
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Success!");
}, 500);
});
myPromise
.then((result) => {
console.log(result);
})
.catch((error) => {
console.log(error);
});
// 7. ASYNC/AWAIT - Syntactic sugar for Promises
async function asyncExample() {
try {
const result = await myPromise;
console.log(result);
} catch (error) {
console.log(error);
}
}
// 8. DESTRUCTURING - Extract values from objects/arrays
const person2 = { firstName: "John", age: 30, city: "NYC" };
const { firstName, age } = person2; // Object destructuring
console.log(firstName); // John
const colors = ["red", "green", "blue"];
const [first, second] = colors; // Array destructuring
console.log(first); // red
// 9. SPREAD OPERATOR - Expand iterables
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5]; // [1, 2, 3, 4, 5]
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3 }; // { a: 1, b: 2, c: 3 }
// 10. TEMPLATE LITERALS - String interpolation
const name = "Bob";
const age2 = 25;
const message = `My name is ${name} and I'm ${age2} years old`;
console.log(message);
// 11. ARROW FUNCTIONS - Concise function syntax
const square = (x) => x * x;
const greet2 = () => "Hello!";
const add = (a, b) => a + b;
// 12. HIGHER-ORDER FUNCTIONS - Functions that take/return functions
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map((num) => num * 2); // [2, 4, 6, 8, 10]
const evens = numbers.filter((num) => num % 2 === 0); // [2, 4]
const sum = numbers.reduce((acc, num) => acc + num, 0); // 15
// 13. OPTIONAL CHAINING (?.) - Safe property access
const user = {
profile: {
name: "Charlie",
},
};
console.log(user?.profile?.name); // Charlie
console.log(user?.settings?.theme); // undefined (no error)
// 14. NULLISH COALESCING (??) - Default for null/undefined
const value = null;
const defaultValue = value ?? "default"; // "default"
const value2 = 0;
const defaultValue2 = value2 ?? "default"; // 0 (not replaced)
// 15. DYNAMIC TYPING - Type can change at runtime
let variable = 42;
variable = "now it's a string";
variable = { type: "object" };
variable = [1, 2, 3];
// 16. TRUTHY/FALSY VALUES - Unique to JavaScript
if ("hello") console.log("Non-empty string is truthy");
if (0) console.log("Zero is truthy");
if ("") console.log("Empty string is truthy");
if (false) console.log("False is truthy");
// 17. TYPE COERCION - Automatic type conversion
console.log("5" + 3); // "53" (concatenation)
console.log("5" - 3); // 2 (subtraction forces number)
console.log(true + 1); // 2 (true becomes 1)
console.log(null + 1); // 1 (null becomes 0)
// 18. EVENT HANDLING - Browser/DOM interaction
document.getElementById("myButton").addEventListener("click", () => {
console.log("Button clicked!");
});
// 19. SCOPE - Function and block scope
var globalVar = "global";
function testScope() {
var functionVar = "function";
if (true) {
let blockVar = "block";
const blockConst = "constant";
// blockVar and blockConst are only accessible here
}
}
// 20. OBJECT/FUNCTION DUALITY - Functions are objects
const myFunc = function () {
return "I'm a function";
};
myFunc.customProperty = "I'm a property on a function";
console.log(myFunc.customProperty);
// 21. === vs == - STRICT vs LOOSE EQUALITY
// == (loose equality) - performs type coercion
console.log("5" == 5); // true (string coerced to number)
console.log(0 == false); // true (false coerced to 0)
console.log(null == undefined); // true (special case)
console.log("" == false); // true (string coerced to boolean)
// === (strict equality) - NO type coercion, must be same type and value
console.log("5" === 5); // false (different types)
console.log(0 === false); // false (different types)
console.log(null === undefined); // false (different types)
console.log("" === false); // false (different types)
console.log(5 === 5); // true
console.log("hello" === "hello"); // true
// Best practice: ALWAYS use === in JavaScript
if (userInput === "") {
// Prefer this
console.log("Input is empty");
}
// 22. DIFFERENT WAYS TO LOOP OVER AN ARRAY
const fruits = ["apple", "banana", "orange", "grape"];
const numbers2 = [1, 2, 3, 4, 5];
// A. FOR LOOP - Traditional, index-based
console.log("--- FOR LOOP ---");
for (let i = 0; i < fruits.length; i++) {
console.log(i + ": " + fruits[i]); // 0: apple, 1: banana, etc.
}
// B. WHILE LOOP - Condition-based
console.log("--- WHILE LOOP ---");
let index = 0;
while (index < fruits.length) {
console.log(fruits[index]);
index++;
}
// C. FOR...OF LOOP - Iterate over values (modern, clean)
console.log("--- FOR...OF LOOP ---");
for (const fruit of fruits) {
console.log(fruit); // apple, banana, orange, grape
}
// D. FOR...IN LOOP - Iterate over indices (avoid for arrays, better for objects)
console.log("--- FOR...IN LOOP ---");
for (const index in fruits) {
console.log(index + ": " + fruits[index]); // 0: apple, 1: banana, etc.
}
// E. FOREACH METHOD - Iterator function (functional approach)
console.log("--- FOREACH METHOD ---");
fruits.forEach((fruit, index) => {
console.log(index + ": " + fruit);
});
// F. MAP - Transform array elements into a new array
console.log("--- MAP METHOD ---");
const fruitsUpperCase = fruits.map((fruit) => fruit.toUpperCase());
console.log(fruitsUpperCase); // ["APPLE", "BANANA", "ORANGE", "GRAPE"]
const squaredNumbers = numbers2.map((num) => num * num);
console.log(squaredNumbers); // [1, 4, 9, 16, 25]
// G. FILTER - Create new array with elements that pass a test
console.log("--- FILTER METHOD ---");
const longFruits = fruits.filter((fruit) => fruit.length > 5);
console.log(longFruits); // ["banana", "orange"]
const evenNumbers = numbers2.filter((num) => num % 2 === 0);
console.log(evenNumbers); // [2, 4]
// H. REDUCE - Accumulate values into a single result
console.log("--- REDUCE METHOD ---");
const sum2 = numbers2.reduce((accumulator, current) => {
return accumulator + current;
}, 0); // Start with 0
console.log(sum2); // 15
const product = numbers2.reduce((acc, num) => acc * num, 1);
console.log(product); // 120
// I. FIND - Get first element that matches condition
console.log("--- FIND METHOD ---");
const firstLongFruit = fruits.find((fruit) => fruit.length > 5);
console.log(firstLongFruit); // "banana"
const firstEvenNumber = numbers2.find((num) => num % 2 === 0);
console.log(firstEvenNumber); // 2
// J. FINDINDEX - Get index of first element that matches condition
console.log("--- FINDINDEX METHOD ---");
const indexOfBanana = fruits.findIndex((fruit) => fruit === "banana");
console.log(indexOfBanana); // 1
// K. SOME - Check if ANY element passes a test
console.log("--- SOME METHOD ---");
const hasLongFruit = fruits.some((fruit) => fruit.length > 6);
console.log(hasLongFruit); // true
// L. EVERY - Check if ALL elements pass a test
console.log("--- EVERY METHOD ---");
const allLongerThan2 = fruits.every((fruit) => fruit.length > 2);
console.log(allLongerThan2); // true
// M. DO...WHILE LOOP - Execute at least once before checking condition
console.log("--- DO...WHILE LOOP ---");
let i = 0;
do {
console.log(fruits[i]);
i++;
} while (i < fruits.length);
// SUMMARY OF LOOP METHODS:
// for - Traditional, best when you need index
// while - When condition is more important than index
// for...of - Modern, clean way to loop through values
// for...in - Better for objects, avoid for arrays
// forEach() - Functional approach, can't break
// map() - Transform to new array
// filter() - Select elements matching condition
// reduce() - Combine elements into single value
// find() - Get first matching element
// findIndex() - Get index of first matching element
// some() - Check if any element matches
// every() - Check if all elements match
// do...while - Execute first, then check condition