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: 1-js/99-js-misc/01-proxy/article.md
+81-81Lines changed: 81 additions & 81 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -729,15 +729,15 @@ Il problema sta quindi nel proxy, alla riga `(*)`.
729
729
2. Il prototype è `userProxy`.
730
730
3. Durante la lettura della proprietà `name` dal proxy, la trappola `get` viene innescata e ritorna la proprietà dell'oggetto originale `target[prop]` alla riga `(*)`.
731
731
732
-
A call to `target[prop]`, when `prop`is a getter, runs its code in the context`this=target`. So the result is`this._name`from the original object `target`, that is: from`user`.
732
+
Un'invocazione di `target[prop]`, nel caso in cui `prop`sia un getter, ne esegue il codice con contesto`this=target`. Quindi il risultato sarà`this._name`dell'oggetto `target`, quindi: da`user`.
733
733
734
-
To fix such situations, we need `receiver`, the third argument of `get` trap. It keeps the correct`this`to be passed to a getter. In our case that's`admin`.
734
+
Per evitare questo, abbiamo bisogno di `receiver`, il terzo argomento della trappola `get`. Questo fa riferimento al`this`corretto, quello che deve essere passato al getter. Nel nostro caso`admin`.
735
735
736
-
How to pass the context for a getter? For a regular function we could use `call/apply`, but that's a getter, it's not "called", just accessed.
736
+
Come possiamo passare il contensto per un getter? Per una funzione regolare potremmo usare `call/apply`, ma questo è un getter, non viene "invocato", ma vi si accede semplicemenete.
737
737
738
-
`Reflect.get`can do that. Everything will work right if we use it.
738
+
`Reflect.get`fa al caso nostro. Tutto funzionerà correttamente se ne facciamo uso.
739
739
740
-
Here's the corrected variant:
740
+
Vediamo la variante corretta:
741
741
742
742
```js run
743
743
let user = {
@@ -766,9 +766,9 @@ alert(admin.name); // Admin
766
766
*/!*
767
767
```
768
768
769
-
Now`receiver`that keeps a reference to the correct `this`(that is `admin`), is passed to the getter using`Reflect.get`in the line`(*)`.
769
+
Ora`receiver`fa riferimento al `this`corretto (cioè `admin`), e verrà passato al getter utilizzando`Reflect.get`, come in riga`(*)`.
770
770
771
-
We can rewrite the trap even shorter:
771
+
Possiamo riscrive la trappola in maniera ancora più breve:
`Reflect` calls are named exactly the same way as traps and accept the same arguments. They were specifically designed this way.
780
+
Le funzioni `reflect` hanno lo stesso nome delle trappole ed accettano gli stessi argomenti. Sono stati progettati in questo modo.
781
781
782
-
So, `return Reflect...`provides a safe no-brainer to forward the operation and make sure we don't forget anything related to that.
782
+
Quindi, `return Reflect...`è un modo sicuro e banale per inoltrare le operazioni ed essere sicuri di non dimenticarci nulla.
783
783
784
-
## Proxy limitations
784
+
## Limitazioni del proxy
785
785
786
-
Proxies provide a unique way to alter or tweak the behavior of the existing objects at the lowest level. Still, it's not perfect. There are limitations.
786
+
I proxy forniscono un modo unico per alterare o aggirare il comportamentoa basso livello degli oggetti esistenti. Non è comunque perfetto. Ha delle limitazioni.
787
787
788
-
### Built-in objects: Internal slots
788
+
### Oggetti integrati: slot interni
789
789
790
-
Many built-in objects, for example`Map`, `Set`, `Date`, `Promise`and others make use of so-called "internal slots".
790
+
Molti oggetti integrati, ad esempio`Map`, `Set`, `Date`, `Promise`e altri, fanno uso dei così detti "internal slots".
791
791
792
-
These are like properties, but reserved for internal, specification-only purposes. For instance, `Map`stores items in the internal slot `[[MapData]]`. Built-in methods access them directly, not via `[[Get]]/[[Set]]` internal methods. So`Proxy`can't intercept that.
792
+
Questi sono come le proprietà, ma sono riservati ad usi interni, fanno parte solamente delle specifiche. Ad esempio, `Map`memorizza gli elementi nello slot interno `[[MapData]]`. I metodi integrati accedono direttamente a questi, non utilizzano i metodi `[[Get]]/[[Set]]`. Quini`Proxy`non potrà intercettarli.
793
793
794
-
Why care? They're internal anyway!
794
+
Perché questo ha importanza? Sono comunque entità interne!
795
795
796
-
Well, here's the issue. After a built-in object like that gets proxied, the proxy doesn't have these internal slots, so built-in methods will fail.
796
+
Non proprio, vediamo qual'è il problema. Dopo aver creato un proxy per un oggetto integrato, il proxy non avrà questi slot interni, quindi i metodi integrati falliranno.
797
797
798
-
For example:
798
+
Ad esempio:
799
799
800
800
```js run
801
801
let map =newMap();
802
802
803
803
let proxy =newProxy(map, {});
804
804
805
805
*!*
806
-
proxy.set('test', 1); //Error
806
+
proxy.set('test', 1); //Errore
807
807
*/!*
808
808
```
809
809
810
-
Internally, a`Map`stores all data in its `[[MapData]]` internal slot. The proxy doesn't have such a slot. The [built-in method`Map.prototype.set`](https://tc39.es/ecma262/#sec-map.prototype.set)method tries to access the internal property `this.[[MapData]]`, but because`this=proxy`, can't find it in`proxy`and just fails.
810
+
Internamente, una`Map`memorizza i suoi dati nello slot `[[MapData]]`. Il proxy non possiede questo slot. Il [metodo integrato`Map.prototype.set`](https://tc39.es/ecma262/#sec-map.prototype.set)prova ad accedere alla proprietà interna `this.[[MapData]]`, ma poiché`this=proxy`, non la trova nel`proxy`e fallisce.
811
811
812
-
Fortunately, there's a way to fix it:
812
+
Fortunatamente, esiste un modo per evitare questo:
813
813
814
814
```js run
815
815
let map =newMap();
@@ -824,24 +824,24 @@ let proxy = new Proxy(map, {
824
824
});
825
825
826
826
proxy.set('test', 1);
827
-
alert(proxy.get('test')); // 1 (works!)
827
+
alert(proxy.get('test')); // 1 (funziona!)
828
828
```
829
829
830
-
Now it works fine, because `get`trap binds function properties, such as `map.set`, to the target object (`map`) itself.
830
+
Ora funziona senza problemi, poiché la trappola `get`si lega alle proprietà della funzione, come `map.set`, per ottenere l'oggetto target (`map`) stesso.
831
831
832
-
Unlike the previous example, the value of`this`inside `proxy.set(...)`will be not `proxy`, but the original `map`. So when the internal implementation of `set`tries to access `this.[[MapData]]` internal slot, it succeeds.
832
+
A differenza dell'esempio precedente, il valore di`this`all'interno di `proxy.set(...)`non sarà `proxy`, ma piuttosto sarà l'oggetto originale `map`. Quindi quando l'implementazione interna di `set`proverà ad accedere allo slot interno `this.[[MapData]]`, l'operazione avverrà con successo.
833
833
834
-
```smart header="`Array`has no internal slots"
835
-
A notable exception: built-in `Array`doesn't use internal slots. That's for historical reasons, as it appeared so long ago.
Un'eccezione degna di nota: l'oggetto integrato `Array`non utilizza slot interni. Questo per ragioni storiche, poiché esistono da moltop tempo.
836
836
837
-
So there's no such problem when proxying an array.
837
+
Quindi non avremo nessun problema nel creare proxy per un array.
838
838
```
839
839
840
-
### Private fields
840
+
### Campi privati
841
841
842
-
A similar thing happens with private class fields.
842
+
Un comportamento simile avviene con i campi privati di una classe.
843
843
844
-
For example, `getName()` method accesses the private `#name` property and breaks after proxying:
844
+
Ad esempio, il metodo `getName()` accede alla proprietà privata `#name` e comporta il fallimento del proxy:
845
845
846
846
```js run
847
847
class User {
@@ -857,15 +857,15 @@ let user = new User();
857
857
user = new Proxy(user, {});
858
858
859
859
*!*
860
-
alert(user.getName()); // Error
860
+
alert(user.getName()); // Errore
861
861
*/!*
862
862
```
863
863
864
-
The reason is that private fields are implemented using internal slots. JavaScript does not use `[[Get]]/[[Set]]`when accessing them.
864
+
La motivazione è che i campi privati sono implementati utilizzando gli slot interni. JavaScript non utilizza `[[Get]]/[[Set]]`per accedervi.
865
865
866
-
In the call `getName()`the value of`this`is the proxied `user`, and it doesn't have the slot with private fields.
866
+
Nell'invocazione `getName()`il valore di`this`è il proxy di `user`, e questo non possiede lo slot interno con i campi privati.
867
867
868
-
Once again, the solution with binding the method makes it work:
868
+
Nuovamente, la soluzione di legare il metodo è corretta anche in questo casoo:
869
869
870
870
```js run
871
871
classUser {
@@ -888,13 +888,13 @@ user = new Proxy(user, {
888
888
alert(user.getName()); // Guest
889
889
```
890
890
891
-
That said, the solution has drawbacks, as explained previously: it exposes the original object to the method, potentially allowing it to be passed further and breaking other proxied functionality.
891
+
Detto quesot, la soluzione avrà degli svantaggi, come spiegato in precedenza: espone l'oggetto originale al metodo, consentendo, potenzialmente, che questo venga passato ulteriormente rompendo la funzionalità avvolta nel proxy.
892
892
893
893
### Proxy != target
894
894
895
-
The proxy and the original object are different objects. That's natural, right?
895
+
Il proxy e l'oggetto originale sono due oggetti differenti. Normale, giusto?
896
896
897
-
So if we use the original object as a key, and then proxy it, then the proxy can't be found:
897
+
Quindi se utilizziamo l'oggetto originale come chiave, e successivamente ne creiamo un proxy, allora il proxy non sarà accessibile:
As we can see, after proxying we can't find`user`in the set`allUsers`, because the proxy is a different object.
920
+
Come possiamo vedere, dopo aver aggiunto il proxy, non riusciamo ad accedere a`user`con il setter`allUsers`, poiché il proxy è un oggetto differente.
921
921
922
-
```warn header="Proxies can't intercept a strict equality test `===`"
923
-
Proxies can intercept many operators, such as `new` (with`construct`), `in` (with`has`), `delete` (with`deleteProperty`) and so on.
922
+
```warn header="I proxy non possono intercettare un test di uguaglianza stretta`===`"
923
+
I proxy possono intercettare molti operatori, come `new` (con`construct`), `in` (con`has`), `delete` (con`deleteProperty`) e così via.
924
924
925
-
But there's no way to intercept a strict equality test for objects. An object is strictly equal to itself only, and no other value.
925
+
Ma non esiste alcun modo per poter intercettare un test di uguaglianza stretta tra oggetti. Un oggetto è strettamente uguale solamente a se stesso, e a nient altro.
926
926
927
-
So all operations and built-in classes that compare objects for equality will differentiate between the object and the proxy. No transparent replacement here.
927
+
Quindi tutte le operazioni ed le classi integrate che verificano l'uguaglianza tra oggetti differenezieranno l'oggetto dal suo proxy. Non c'è alcun sistema di sostituzione "trasparente" in questo caso.
928
928
```
929
929
930
-
## Revocable proxies
930
+
## Proxy revocabili
931
931
932
-
A *revocable* proxy is a proxy that can be disabled.
932
+
Un proxy *revocabile* è un proxy che può essere disabilitato.
933
933
934
-
Let's say we have a resource, and would like to close access to it any moment.
934
+
Ipotizziamo di avere una risorsa, di cui vorremo poter bloccare gli accessi in qualsiasi momento.
935
935
936
-
What we can do is to wrap it into a revocable proxy, without any traps. Such a proxy will forward operations to object, and we can disable it at any moment.
936
+
Quello che possiamo fare è creare un proxy *revocabile*, senza alcuna trappola. Un proxy di questo tipo, inoltrerà tutte le operazioni all'oggetto originale, e possiamo disabialitarlo in ogni momento.
937
937
938
-
The syntax is:
938
+
La sintassi da utilizzare è la seguente:
939
939
940
940
```js
941
941
let {proxy, revoke} = Proxy.revocable(target, handler)
942
942
```
943
943
944
-
The call returns an object with the`proxy`and`revoke`function to disable it.
944
+
L'invocazione ritorna un oggetto con le funzioni`proxy`e`revoke`per disabilitarlo.
945
945
946
-
Here's an example:
946
+
Vediamo un esempio:
947
947
948
948
```js run
949
949
let object = {
@@ -952,23 +952,23 @@ let object = {
952
952
953
953
let {proxy, revoke} =Proxy.revocable(object, {});
954
954
955
-
//pass the proxy somewhere instead of object...
956
-
alert(proxy.data); //Valuable data
955
+
//passiamo il proxy da qualche parte, piuttosto dell'oggetto...
956
+
alert(proxy.data); //Dati preziosi
957
957
958
-
//later in our code
958
+
//più tardi nel nostro codice
959
959
revoke();
960
960
961
-
//the proxy isn't working any more (revoked)
962
-
alert(proxy.data); //Error
961
+
//il proxy non funzionerà più (revocato)
962
+
alert(proxy.data); //Errore
963
963
```
964
964
965
-
A call to `revoke()`removes all internal references to the target object from the proxy, so they are no longer connected.
965
+
L'invocazione di `revoke()`rimuove dal proxy tutti i referimenti interni all'oggetto, quindi questi non risulteranno essere più connessi.
966
966
967
-
Initially, `revoke`is separate from `proxy`, so that we can pass `proxy`around while leaving `revoke`in the current scope.
967
+
Inizialmente, `revoke` è separato da `proxy`, in questo modo possiamo passare il `proxy`in giro, mantenendo il `revoke`nello scope attuale.
968
968
969
-
We can also bind `revoke`method to proxy by setting`proxy.revoke = revoke`.
969
+
Possiamo anche legare il metodo `revoke`al proxy, impostando`proxy.revoke = revoke`.
970
970
971
-
Another option is to create a `WeakMap`that has `proxy`as the key and the corresponding `revoke`as the value, that allows to easily find `revoke`for a proxy:
971
+
Un'altra opzione è quela di creare una `WeakMap`che possiede il `proxy`come chiave e il corrispondente `revoke`come valore, questo consente di trovare facilemente il `revoke`per un proxy:
972
972
973
973
```js run
974
974
*!*
@@ -983,51 +983,51 @@ let {proxy, revoke} = Proxy.revocable(object, {});
983
983
984
984
revokes.set(proxy, revoke);
985
985
986
-
// ..somewhere else in our code..
986
+
// ..da qualche altra parte nel nostro codice..
987
987
revoke =revokes.get(proxy);
988
988
revoke();
989
989
990
-
alert(proxy.data); //Error (revoked)
990
+
alert(proxy.data); //Errore (revocato)
991
991
```
992
992
993
-
We use `WeakMap`instead of`Map`here because it won't block garbage collection. If a proxy object becomes "unreachable" (e.g. no variable references it any more), `WeakMap`allows it to be wiped from memory together with its `revoke`that we won't need any more.
993
+
In questo casol, utilizziamo una `WeakMap`piuttosto di`Map`in modo che non blocchi il processo di garbage collection. Se un proxy diventa "irragiungibile" (e.g. nessuna variabile fa riferimento ad esso), `WeakMap`consente di rimuoverlo dalla memoria insieme al relativo `revoke`che non sarà più necessario.
`Proxy`is a wrapper around an object, that forwards operations on it to the object, optionally trapping some of them.
1002
+
Il `Proxy`è un contenitore per un oggetto, che inoltra tutte le operazioni su di esso all'oggetto originale, e consente di definire delle "trappole" per determinate operazioni.
1003
1003
1004
-
It can wrap any kind of object, including classes and functions.
1004
+
E' possile creare un proxy per qualsiasi tipo di oggetto, incluse le classi e le funzioni.
1005
1005
1006
-
The syntax is:
1006
+
La sintassi da utilizzare è la seguente:
1007
1007
1008
1008
```js
1009
1009
let proxy =newProxy(target, {
1010
-
/*traps*/
1010
+
/*trappole*/
1011
1011
});
1012
1012
```
1013
1013
1014
-
...Then we should use`proxy`everywhere instead of `target`. A proxy doesn't have its own properties or methods. It traps an operation if the trap is provided, otherwise forwards it to`target` object.
1014
+
...Successivamente, dovremmo utilizzare il`proxy`ovunque, ed evitare l'utilizzo di `target`. Un proxy non possiede proprietà o metodi propri. Si occupa di intercettare le operazioni (se sono definite le relative trappole), altrimenti le inoltra all'oggetto`target`.
1015
1015
1016
-
We can trap:
1017
-
-Reading (`get`), writing (`set`), deleting (`deleteProperty`) a property (even a non-existing one).
1018
-
-Calling a function (`apply` trap).
1019
-
-The`new`operator (`construct` trap).
1020
-
-Many other operations (the full list is at the beginning of the article and in the [docs](mdn:/JavaScript/Reference/Global_Objects/Proxy)).
1016
+
Possiamo intercettare:
1017
+
-Lettura (`get`), scrittura (`set`), rimozione (`deleteProperty`) di una proprietà (anche di quelle non esistenti).
1018
+
-Invocazione di funzione (trappola `apply`).
1019
+
-Operatore`new`(trappola `construct`).
1020
+
-Molte altre operazioni (puoi trovare la lista completa a inizio articolo e nella [documentazione](mdn:/JavaScript/Reference/Global_Objects/Proxy)).
1021
1021
1022
-
That allows us to create "virtual" properties and methods, implement default values, observable objects, function decorators and so much more.
1022
+
Questo ci consente di creare proprietà e motodi "virtuali", implementare valori di default, oggetti observables, decorators e molto altro.
1023
1023
1024
-
We can also wrap an object multiple times in different proxies, decorating it with various aspects of functionality.
1024
+
Possiamo anche costruire proxy multipli di un oggetto, decorandolo con divers e funzionalità.
1025
1025
1026
-
The[Reflect](mdn:/JavaScript/Reference/Global_Objects/Reflect)API is designed to complement [Proxy](mdn:/JavaScript/Reference/Global_Objects/Proxy). For any `Proxy` trap, there's a`Reflect`call with same arguments. We should use those to forward calls to target objects.
1026
+
L'API[Reflect](mdn:/JavaScript/Reference/Global_Objects/Reflect)è stata progettata per completare l'utilizzo dei [Proxy](mdn:/JavaScript/Reference/Global_Objects/Proxy). Per ogni trappola `Proxy`, esiste un'invocazione di`Reflect`con gli stessi argomenti. Possiamo utilizzarlo per inoltrare le invocazioni agli oggetti target.
1027
1027
1028
-
Proxies have some limitations:
1028
+
I proxy hanno però delle limitazioni:
1029
1029
1030
-
-Built-in objects have "internal slots", access to those can't be proxied. See the workaround above.
1031
-
-The same holds true for private class fields, as they are internally implemented using slots. So proxied method calls must have the target object as `this`to access them.
1032
-
-Object equality tests `===`can't be intercepted.
1033
-
- Performance: benchmarks depend on an engine, but generally accessing a property using a simplest proxy takes a few times longer. In practice that only matters for some "bottleneck" objects though.
1030
+
-Gli oggetti integrati possiedono degli "slot interni", ma l'accesso a questi non può essere intercettato dai proxy. Guardate il workaround descritto sopra.
1031
+
-Lo stesso vale per i campi privati della classe, questi vengono implementati internametne utilizzando gli slot. Quindi le invocazioni dei metodi tramite proxy, devono possedere il target object asseganto a `this`per potervi accedere.
1032
+
-I test di uguaglianza `===`non possono essere intercettati.
1033
+
- Performance: i benchmark dipendono molto dal motore JavaScript, ma generalmente l'accesso alle proprietà utilizzando un proxy, richiede più tempo. Anche se nella pratica, questo ha importanza solo per oggetti che creano "colli di bottiglia".
0 commit comments