Observable
Créez une fonction makeObservable(target)
qui “rend l’objet observable” en renvoyant un proxy.
Voici comment cela devrait fonctionner:
function makeObservable(target) {
/* your code */
}
let user = {};
user = makeObservable(user);
user.observe((key, value) => {
alert(`SET ${key}=${value}`);
});
user.name = "John"; // alerts: SET name=John
En d’autres termes, un objet retourné par makeObservable
est exactement comme celui d’origine, mais possède également la méthode observe(handler)
qui définit la fonction de handler
à appeler lors de tout changement de propriété.
Chaque fois qu’une propriété change, le handler(key, value)
est appelé avec le nom et la valeur de la propriété.
P.S. Dans cette tâche, veillez uniquement à écrire sur une propriété. D’autres opérations peuvent être implémentées de manière similaire.
La solution se compose de deux parties:
- Chaque fois que
.observe(handler)
est appelé, nous devons nous souvenir du handler quelque part, pour pouvoir l’appeler plus tard. Nous pouvons stocker des handler directement dans l’objet, en utilisant notre symbole comme clé de propriété - Nous avons besoin d’un proxy avec le piège
set
pour appeler les handler en cas de changement
let handlers = Symbol('handlers');
function makeObservable(target) {
// 1. initialiser le stockage de l'handler
target[handlers] = [];
// Stocker la fonction de l'handler dans un tableau pour les appels futurs
target.observe = function(handler) {
this[handlers].push(handler);
};
// 2. Créer un proxy pour gérer les modifications
return new Proxy(target, {
set(target, property, value, receiver) {
let success = Reflect.set(...arguments); // transmettre l'opération à l'objet
if (success) { // s'il n'y a pas eu d'erreur lors de la définition de la propriété
// appeler tous les handler
target[handlers].forEach(handler => handler(property, value));
}
return success;
}
});
}
let user = {};
user = makeObservable(user);
user.observe((key, value) => {
alert(`SET ${key}=${value}`);
});
user.name = "John";