You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: JavaScript/functions.md
+158-2Lines changed: 158 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -143,7 +143,7 @@ const obj = {
143
143
}
144
144
145
145
obj.getName(); // "Krishna" this refers to obj which called the method.
146
-
obj.getArrowName(); //undefined
146
+
obj.getArrowName(); //undefined this refers to global object.
147
147
```
148
148
#### 3. Constructor Function
149
149
When a function is used as a constructor with the new keyword, this refers to the newly created object instance.
@@ -295,7 +295,163 @@ async function processUserData() {
295
295
processUserData();
296
296
```
297
297
298
-
## Closure?
298
+
299
+
**1. Callbacks**
300
+
301
+
***What they are:** A callback is a function that is passed as an argument to another function and is executed *after* the first function completes its task. They are the traditional way to handle asynchronous operations in JavaScript.
302
+
303
+
***Why they're used:** JavaScript is single-threaded and non-blocking. This means that long-running operations (like network requests or file I/O) shouldn't halt the execution of the rest of your code. Callbacks allow you to start an operation and then specify what should happen once it's finished, without blocking the main thread.
304
+
305
+
***Example:**
306
+
307
+
```javascript
308
+
functionfetchData(url, callback) {
309
+
// Simulate an asynchronous operation (like fetching data from an API)
310
+
setTimeout(() => {
311
+
constdata= { name:"John Doe", age:30 }; // Sample data
312
+
callback(data); // Call the callback function with the data
313
+
}, 1000); // Simulate a 1-second delay
314
+
}
315
+
316
+
functionprocessData(data) {
317
+
console.log("Data received:", data);
318
+
// Perform some operations on the received data
319
+
console.log("Name:", data.name);
320
+
console.log("Age:", data.age);
321
+
}
322
+
323
+
fetchData("some_url", processData); // Pass processData as the callback
324
+
325
+
console.log("Fetching data..."); // This will execute *before* the data is fetched
326
+
327
+
// Output:
328
+
// Fetching data...
329
+
// Data received: { name: 'John Doe', age: 30 }
330
+
// Name: John Doe
331
+
// Age: 30
332
+
```
333
+
334
+
***Explanation:**`fetchData` simulates an asynchronous operation. `processData` is the callback. Notice how "Fetching data..." logs *before* the data is actually received. This demonstrates the non-blocking nature of asynchronous JavaScript. Once the `setTimeout` finishes (after 1 second), it calls the `processData` function, passing the retrieved data.
335
+
336
+
***Callback Hell (Pyramid of Doom):** A major drawback of callbacks is that nested asynchronous operations can lead to complex and hard-to-read code, often called "callback hell" or the "pyramid of doom."
337
+
338
+
```javascript
339
+
// Example of nested callbacks (callback hell)
340
+
getData1((data1) => {
341
+
getData2(data1, (data2) => {
342
+
getData3(data2, (data3) => {
343
+
// ... more nested callbacks ...
344
+
});
345
+
});
346
+
});
347
+
```
348
+
349
+
**2. Promises**
350
+
351
+
***What they are:** Promises are a cleaner way to handle asynchronous operations. A Promise represents the eventual result of an asynchronous operation. It can be in one of three states:
352
+
**Pending:* The initial state, before the operation completes.
353
+
**Fulfilled (Resolved):* The operation completed successfully.
354
+
**Rejected:* The operation failed.
355
+
356
+
***Why they're used:** Promises make asynchronous code more readable and manageable, avoiding the problems of callback hell. They provide a more structured way to handle asynchronous results and errors.
console.log("Fetching data with Promise..."); // This executes first
389
+
390
+
// Output:
391
+
// Fetching data with Promise...
392
+
// Data received: { name: 'Jane Doe', age: 25 }
393
+
// Name: Jane Doe
394
+
// Age: 25
395
+
// Data processed further: 50
396
+
```
397
+
398
+
***Explanation:**`fetchDataPromise` returns a Promise. The `.then()` method is used to handle the fulfilled state (when the data is successfully retrieved). The `.catch()` method handles the rejected state (if there's an error). Promise chaining allows you to perform a sequence of asynchronous operations in a more organized way.
399
+
400
+
**3. Async/Await**
401
+
402
+
***What they are:**`async` and `await` make asynchronous code look and behave a bit more like synchronous code, making it even easier to read and understand. `async` is used to declare a function as asynchronous, and `await` is used inside an `async` function to pause execution until a Promise resolves (or rejects).
403
+
404
+
***Why they're used:** Async/await simplifies asynchronous code even further than Promises, making it more concise and easier to follow the control flow. It's built on top of Promises.
405
+
406
+
***Example:**
407
+
408
+
```javascript
409
+
asyncfunctionfetchDataAsync(url) {
410
+
try {
411
+
constdata=awaitfetchDataPromise(url); // Wait for the Promise to resolve
412
+
console.log("Data received (async/await):", data);
413
+
console.log("Name:", data.name);
414
+
console.log("Age:", data.age);
415
+
return data;
416
+
} catch (error) {
417
+
console.error("Error (async/await):", error);
418
+
}
419
+
}
420
+
421
+
asyncfunctionprocessDataAsync() {
422
+
constdata=awaitfetchDataAsync("some_url");
423
+
console.log("Data processed further (async/await):", data.age*2);
424
+
}
425
+
426
+
427
+
processDataAsync();
428
+
console.log("Fetching data with async/await...");
429
+
430
+
// Output:
431
+
// Fetching data with async/await...
432
+
// Data received (async/await): { name: 'Jane Doe', age: 25 }
433
+
// Name: Jane Doe
434
+
// Age: 25
435
+
// Data processed further (async/await): 50
436
+
```
437
+
438
+
***Explanation:** The `async` keyword makes `fetchDataAsync` and `processDataAsync` asynchronous functions. Inside `fetchDataAsync`, `await fetchDataPromise(url)` pauses execution until the Promise returned by `fetchDataPromise` resolves. The `try...catch` block handles any potential errors. `async/await` makes the code look much more like synchronous code, even though it's asynchronous under the hood.
| Readability | Can become complex (callback hell) | Improved readability | Very readable, synchronous-like syntax |
446
+
| Error Handling | Can be cumbersome | Easier with `.catch()`| Easier with `try...catch`|
447
+
| Chaining | Difficult | Easy | Easy |
448
+
| Under the Hood | Basic asynchronous mechanism | Built on callbacks, more structured | Built on Promises, syntactic sugar |
449
+
450
+
451
+
In modern JavaScript development, Promises and especially async/await are the preferred way to handle asynchronous operations. They lead to cleaner, more maintainable, and easier-to-understand code. While callbacks are still used in some situations (especially in older code or with certain APIs), Promises and async/await are the recommended approach for most asynchronous tasks.
452
+
453
+
454
+
## Closure
299
455
A closure is a feature in JavaScript where an inner function has access to the outer (enclosing) function’s variables. In JavaScript, closures are created every time a function is created, at function creation time.
300
456
301
457
- Variables declared in the outer function’s scope.
0 commit comments