Skip to content

Proxy and Reflect #188

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions 1-js/99-js-misc/01-proxy/01-error-nonexisting/task.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# Error on reading non-existant property
# Erreur lors de la lecture d'une propriété inexistante

Usually, an attempt to read a non-existant property returns `undefined`.
Habituellement, une tentative de lecture d'une propriété inexistante renvoie `undefined`.

Create a proxy that throws an error for an attempt to read of a non-existant property instead.
Créez à la place un proxy qui génère une erreur pour une tentative de lecture d'une propriété inexistante.

That can help to detect programming mistakes early.
Cela peut aider à détecter précocement les erreurs de programmation.

Write a function `wrap(target)` that takes an object `target` and return a proxy that adds this functionality aspect.
Écrivez une fonction `wrap(target)` qui prend un objet `target` et retourne un proxy qui ajoute cet aspect fonctionnel.

That's how it should work:
Voilà comment cela devrait fonctionner:

```js
let user = {
Expand All @@ -27,6 +27,6 @@ user = wrap(user);

alert(user.name); // John
*!*
alert(user.age); // ReferenceError: Property doesn't exist "age"
alert(user.age); // ReferenceError: la propriété n'existe pas "age"
*/!*
```
4 changes: 2 additions & 2 deletions 1-js/99-js-misc/01-proxy/02-array-negative/solution.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ let array = [1, 2, 3];
array = new Proxy(array, {
get(target, prop, receiver) {
if (prop < 0) {
// even if we access it like arr[1]
// prop is a string, so need to convert it to number
// même si on y accède comme arr[1]
// prop est une chaîne, il faut donc la convertir en nombre
prop = +prop + target.length;
}
return Reflect.get(target, prop, receiver);
Expand Down
20 changes: 10 additions & 10 deletions 1-js/99-js-misc/01-proxy/02-array-negative/task.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@

# Accessing array[-1]
# Accès au tableau [-1]

In some programming languages, we can access array elements using negative indexes, counted from the end.
Dans certains langages de programmation, nous pouvons accéder aux éléments du tableau à l'aide d'index négatifs, comptés à partir de la fin.

Like this:
comme ça:

```js
let array = [1, 2, 3];

array[-1]; // 3, the last element
array[-2]; // 2, one step from the end
array[-3]; // 1, two steps from the end
array[-1]; // 3, le premier élément en partant de la fin
array[-2]; // 2, le second élément en partant de la fin
array[-3]; // 1, le troisième élément en partant de la fin
```

In other words, `array[-N]` is the same as `array[array.length - N]`.
En d'autres termes, `array[-N]` est identique à `array[array.length - N]`.

Create a proxy to implement that behavior.
Créez un proxy pour implémenter ce comportement.

That's how it should work:
Voilà comment cela devrait fonctionner:

```js
let array = [1, 2, 3];
Expand All @@ -29,5 +29,5 @@ array = new Proxy(array, {
alert( array[-1] ); // 3
alert( array[-2] ); // 2

// Other array functionality should be kept "as is"
// Les autres fonctionnalités de array doivent être conservées
```
18 changes: 9 additions & 9 deletions 1-js/99-js-misc/01-proxy/03-observable/solution.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
The solution consists of two parts:
La solution se compose de deux parties:

1. Whenever `.observe(handler)` is called, we need to remember the handler somewhere, to be able to call it later. We can store handlers right in the object, using our symbol as the property key.
2. We need a proxy with `set` trap to call handlers in case of any change.
1. 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é
2. Nous avons besoin d'un proxy avec le piège `set` pour appeler les handler en cas de changement

```js run
let handlers = Symbol('handlers');

function makeObservable(target) {
// 1. Initialize handlers store
// 1. initialiser le stockage de l'handler
target[handlers] = [];

// Store the handler function in array for future calls
// Stocker la fonction de l'handler dans un tableau pour les appels futurs
target.observe = function(handler) {
this[handlers].push(handler);
};

// 2. Create a proxy to handle changes
// 2. Créer un proxy pour gérer les modifications
return new Proxy(target, {
set(target, property, value, receiver) {
let success = Reflect.set(...arguments); // forward the operation to object
if (success) { // if there were no error while setting the property
// call all handlers
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;
Expand Down
10 changes: 5 additions & 5 deletions 1-js/99-js-misc/01-proxy/03-observable/task.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@

# Observable

Create a function `makeObservable(target)` that "makes the object observable" by returning a proxy.
Créez une fonction `makeObservable(target)` qui "rend l'objet observable" en renvoyant un proxy.

Here's how it should work:
Voici comment cela devrait fonctionner:

```js run
function makeObservable(target) {
Expand All @@ -20,8 +20,8 @@ user.observe((key, value) => {
user.name = "John"; // alerts: SET name=John
```

In other words, an object returned by `makeObservable` is just like the original one, but also has the method `observe(handler)` that sets `handler` function to be called on any property change.
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é.

Whenever a property changes, `handler(key, value)` is called with the name and value of the property.
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. In this task, please only take care about writing to a property. Other operations can be implemented in a similar way.
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.
Loading