Skip to content

Proxy and Reflect #451

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 12 commits into from
Jan 25, 2021
4 changes: 2 additions & 2 deletions 1-js/99-js-misc/01-proxy/01-error-nonexisting/solution.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function wrap(target) {
if (prop in target) {
return Reflect.get(target, prop, receiver);
} else {
throw new ReferenceError(`Property doesn't exist: "${prop}"`)
throw new ReferenceError(`La propiedad no existe: "${prop}"`)
}
}
});
Expand All @@ -19,5 +19,5 @@ function wrap(target) {
user = wrap(user);

alert(user.name); // John
alert(user.age); // ReferenceError: Property doesn't exist: "age"
alert(user.age); // ReferenceError: La propiedad no existe: "age"
```
16 changes: 8 additions & 8 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-existent property
# Error al leer una propiedad no existente

Usually, an attempt to read a non-existent property returns `undefined`.
Usualmente, el intento de leer una propiedad que no existe devuelve `undefined`.

Create a proxy that throws an error for an attempt to read of a non-existent property instead.
Crea en su lugar un proxy que arroje un error por intentar leer una propiedad no existente.

That can help to detect programming mistakes early.
Esto puede ayudar a detectar equivocaciones en la programación en forma temprana.

Write a function `wrap(target)` that takes an object `target` and return a proxy that adds this functionality aspect.
Escribe una función `wrap(target)` que tome un objeto `target` y devuelva un proxy que agregue este aspecto de funcionalidad.

That's how it should work:
Así es como debe funcionar:

```js
let user = {
Expand All @@ -18,7 +18,7 @@ let user = {
function wrap(target) {
return new Proxy(target, {
*!*
/* your code */
/* tu código */
*/!*
});
}
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 propiedad no existe: "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
// incluso aunque la accedamos como arr[1]
// prop es un string, así que necesitamos convertirla a number
prop = +prop + target.length;
}
return Reflect.get(target, prop, receiver);
Expand Down
22 changes: 11 additions & 11 deletions 1-js/99-js-misc/01-proxy/02-array-negative/task.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@

# Accessing array[-1]
# Accediendo a array[-1]

In some programming languages, we can access array elements using negative indexes, counted from the end.
En algunos lenguajes de programación podemos acceder a los arrays usando índices negativos, contando desde el final.

Like this:
Como esto:

```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, el último elemento
array[-2]; // 2, el penúltimo elemento, uno antes del final
array[-3]; // 1, el antepenúltimo elemento, dos antes el final
```

In other words, `array[-N]` is the same as `array[array.length - N]`.
En otras palabras, `array[-N]` es lo mismo que `array[array.length - N]`.

Create a proxy to implement that behavior.
Crea un proxy para implementar tal comportamiento.

That's how it should work:
Así es como debe funcionar:

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

array = new Proxy(array, {
/* your code */
/* tu código */
});

alert( array[-1] ); // 3
alert( array[-2] ); // 2

// Other array functionality should be kept "as is"
// el resto de la funcionalidad debe mantenerse igual.
```
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 solución consiste de dos partes:

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. Cuando `.observe(handler)` es llamado, necesitamos recordar el manejador 'handler' en algún lugar para poder llamarlo después. Podemos almacenar los manejadores directamente en el objeto, usando nuestro symbol como clave de la propiedad.
2. Necesitamos un proxy con la trampa `set` que llame a los manejadores en caso de cualquier cambio.

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

function makeObservable(target) {
// 1. Initialize handlers store
// 1. Inicializa el almacén de manejadores
target[handlers] = [];

// Store the handler function in array for future calls
// Almacena la función manejadora en el array para llamadas futuras
target.observe = function(handler) {
this[handlers].push(handler);
};

// 2. Create a proxy to handle changes
// 2. Crea un proxy para manejar cambios
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); // reenvía la operación al objeto
if (success) { // si no hay errores al establecer la propiedad
// llama a todos los manejadores
target[handlers].forEach(handler => handler(property, value));
}
return success;
Expand Down
14 changes: 7 additions & 7 deletions 1-js/99-js-misc/01-proxy/03-observable/task.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@

# Observable

Create a function `makeObservable(target)` that "makes the object observable" by returning a proxy.
Crea una función `makeObservable(target)` que "haga el objeto observable" devolviendo un proxy.

Here's how it should work:
Así es como debe funcionar:

```js run
function makeObservable(target) {
/* your code */
/* tu código */
}

let user = {};
Expand All @@ -17,11 +17,11 @@ user.observe((key, value) => {
alert(`SET ${key}=${value}`);
});

user.name = "John"; // alerts: SET name=John
user.name = "John"; // alerta: 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 otras palabras, un objeto devuelto por `makeObservable` es como el original pero que también tiene el método `observe(handler)` que establece una función `handler` que será llamada en cualquier cambio de propiedad.

Whenever a property changes, `handler(key, value)` is called with the name and value of the property.
cada vez que una propiedad cambie, `handler(key, value)` es llamado con el nombre y el valor de la propiedad.

P.S. In this task, please only take care about writing to a property. Other operations can be implemented in a similar way.
P.D. En esta tarea, solo toma en cuenta la escritura de una propiedad. Otras operaciones pueden ser implementadas de manera similar.
Loading