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
* Explora el concepto de "decorador" y muestra cómo crearlo
5
+
* con un ejemplo genérico.
6
+
*
7
+
* DIFICULTAD EXTRA (opcional):
8
+
* Crea un decorador que sea capaz de contabilizar cuántas veces
9
+
* se ha llamado a una función y aplícalo a una función de tu elección.
10
+
*/
11
+
12
+
letlog=console.log;
13
+
14
+
window.addEventListener('load',()=>{
15
+
constbody=document.querySelector('body');
16
+
consttitle=document.createElement('h1');
17
+
18
+
body.style.setProperty('background','#000');
19
+
body.style.setProperty('text-align','center');
20
+
21
+
title.textContent='Retosparaprogramadores #24.';
22
+
title.style.setProperty('font-size','3.5vmax');
23
+
title.style.setProperty('color','#fff');
24
+
title.style.setProperty('line-height','100vh');
25
+
26
+
body.appendChild(title);
27
+
28
+
setTimeout(()=>{
29
+
alert('Retosparaprogramadores #24. Please open the Browser Developer Tools.');
30
+
},2000);
31
+
log('Retosparaprogramadores #24');
32
+
});
33
+
34
+
35
+
/* The decorator pattern is a structural design pattern that allows behavior to be added to individual objects, either statically or dynamically, without affecting the behavior of other objects from the same class. In JavaScript, decorators can be implemented using higher-order functions. */
36
+
37
+
// Generic decorator function
38
+
functiondecorator(fn){
39
+
returnfunction(...args){
40
+
log("Before calling the function");
41
+
constresult=fn(...args);
42
+
log("After calling the function");
43
+
returnresult;
44
+
};
45
+
}
46
+
47
+
// Decorator to log execution time
48
+
functionlogExecutionTime(fn){
49
+
returnasyncfunction(...args){
50
+
conststart=performance.now();// Start time
51
+
constresult=awaitfn(...args);
52
+
constend=performance.now();// End time
53
+
log(`Execution time for ${fn.name}: ${end-start} milliseconds`);
54
+
returnresult;
55
+
};
56
+
}
57
+
58
+
// Example function that simulates a time-consuming task
59
+
functionfetchData(){
60
+
returnnewPromise((resolve)=>{
61
+
setTimeout(()=>{
62
+
resolve("Data fetched!");
63
+
},3000);
64
+
});
65
+
}
66
+
67
+
// Decorated function
68
+
constloggedFetchData=logExecutionTime(fetchData);// Execution time for fetchData: 10732 milliseconds
69
+
70
+
//Note: the fetchData() has delate of 3 seconds so the previus msj will be logged at the end after that time.
71
+
72
+
// Using the decorated function
73
+
loggedFetchData().then(result=>log(result));// Data fetched!
74
+
75
+
76
+
//EXTRA DIFICULTY EXERCISE
77
+
78
+
// Decorator to count function calls
79
+
functioncountCalls(fn){
80
+
letcallCount=0;// Private variable to keep track of calls through closure
81
+
82
+
returnfunction(...args){
83
+
callCount++;
84
+
log(`Function has been called ${callCount} times.`);
85
+
returnfn(...args);
86
+
};
87
+
}
88
+
89
+
// Original function
90
+
functionhiGirl(){
91
+
log('Hi Girl! \uD83C\uDF39');
92
+
return'\uD83C\uDF3C';
93
+
}
94
+
95
+
// Decorated function
96
+
constcountedhiGirl=countCalls(hiGirl);
97
+
98
+
// Using the decorated function
99
+
log(countedhiGirl());// Function has been called 1 times. Hi Girl! 🌹
100
+
log(countedhiGirl());// Function has been called 2 times. Hi Girl! 🌹
101
+
log(countedhiGirl());// Function has been called 3 times. Hi Girl! 🌹
102
+
103
+
// Trying to access countedhiGirl directly will result in an error
104
+
// log(countedhiGirl); // Uncaught ReferenceError: countedhiGirl is not defined
105
+
106
+
107
+
108
+
/* NOTE: When you define a function inside another function, the inner function creates a private scope. This means that the inner function has access to the variables and parameters of the outer function, but those variables are not accessible from outside the outer function. This is a key feature of closures in JavaScript.
109
+
110
+
Explanation of Private Scope with Closures
111
+
In the context of the decorator pattern, this private scope allows us to maintain state (like the callCount in the counting decorator) without exposing it to the outside world. Here’s a breakdown of how this works:
112
+
113
+
Closure: When the inner function is returned from the outer function, it retains access to the outer function's variables. This is known as a closure. The inner function can use and modify these variables even after the outer function has finished executing.
114
+
Private Variables: Variables defined in the outer function (like callCount) are not accessible from outside the function. This means that you cannot directly modify or read callCount from outside the countCalls function, which effectively makes it private.*/
0 commit comments