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
+71-71Lines changed: 71 additions & 71 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -436,27 +436,27 @@ user = {
436
436
```
437
437
438
438
439
-
A call to `user.checkPassword()`gets proxied `user`as`this` (the object before dot becomes`this`), so when it tries to access`this._password`, the `get`trap activates (it triggers on any property read) and throws an error.
439
+
Un'invocazione di `user.checkPassword()`passerà al proxy `user`come`this` (l'oggetto prima del punto diventa`this`), quindi quando proverà ad accedere a`this._password`, la trappola `get`si attiverà (vieni innescata alla lettura di qualsiasi proprietà) e genererà un errore.
440
440
441
-
So we bind the context of object methods to the original object, `target`, in the line `(*)`. Then their future calls will use `target`as`this`, without any traps.
441
+
Quindi leghiamo il contesto dei metodi dell'oggetto all'oggetto originale, `target`, alla riga `(*)`. Le future invocazioni utilizzeranno `target`come`this`, senza alcuna trappola.
442
442
443
-
That solution usually works, but isn't ideal, as a method may pass the unproxied object somewhere else, and then we'll get messed up: where's the original object, and where's the proxied one?
443
+
Questa soluzione solitamenete funziona, ma non è ideale, poiché un metodo potrebbe passare l'oggetto senza proxy ovunque, e a quel punto faremmo un errore: dov'è l'oggetto originale, e dov'è quello con il proxy?
444
444
445
-
Besides, an object may be proxied multiple times (multiple proxies may add different "tweaks" to the object), and if we pass an unwrapped object to a method, there may be unexpected consequences.
445
+
Oltretutto, un oggetto potrebbe essere racchiuso in più proxy (più proxy potrebbero aggiungere diverse funzionalità all'oggetto), e nel caso in cui passassimo un oggettto senza proxy ad un metodo, potremmo ottenere conseguenze inaspettate.
446
446
447
-
So, such a proxy shouldn't be used everywhere.
447
+
Quindi, un proxy del genere non dovrebbe essere utilizzato ovunque.
448
448
449
-
```smart header="Private properties of a class"
450
-
Modern JavaScript engines natively support private properties in classes, prefixed with `#`. They are described in the article <info:private-protected-properties-methods>. No proxies required.
449
+
```smart header="Proprietà private di una classe"
450
+
I motori JavaScript moderni, offrono un supporto nativo per le proprietà private nelle classi, aggiungendo il prefisso `#`. Questi sono descritti nell'articolo <info:private-protected-properties-methods>. Non è richiesto alcun proxy.
451
451
452
-
Such properties have their own issues though. In particular, they are not inherited.
452
+
Anche se questo genere di proprietà hanno i loro problemi. In particolare, questi non vengono ereditati.
453
453
```
454
454
455
-
## "In range" with "has" trap
455
+
## "In range" con la trappola "has"
456
456
457
-
Let's see more examples.
457
+
Vediamo altri esempi.
458
458
459
-
We have a range object:
459
+
Abbiamo un oggetto `range`:
460
460
461
461
```js
462
462
let range = {
@@ -465,16 +465,16 @@ let range = {
465
465
};
466
466
```
467
467
468
-
We'd like to use the `in`operator to check that a number is in `range`.
468
+
Vorremmo usare l'operatore `in`per verificare che un numero appartenga al`range`.
469
469
470
-
The `has`trap intercepts `in` calls.
470
+
La trappola `has`intercetta le invocazioni di `in`.
471
471
472
472
`has(target, property)`
473
473
474
-
-`target` -- is the target object, passed as the first argument to`new Proxy`,
475
-
-`property` -- property name
474
+
-`target` -- è l'oggetto target, passanto come primo argomento in`new Proxy`,
475
+
-`property` -- nome della proprietà
476
476
477
-
Here's the demo:
477
+
Qui vediamo la demo:
478
478
479
479
```js run
480
480
let range = {
@@ -496,27 +496,27 @@ alert(50 in range); // false
496
496
*/!*
497
497
```
498
498
499
-
Nice syntactic sugar, isn't it? And very simple to implement.
499
+
Semplice zucchero sintattico, vero? Molto semplice da implementare.
500
500
501
-
## Wrapping functions: "apply" [#proxy-apply]
501
+
## Wrapping con funzioni: "apply" [#proxy-apply]
502
502
503
-
We can wrap a proxy around a function as well.
503
+
Possiamo costruire un proxy anche per funzioni.
504
504
505
-
The `apply(target, thisArg, args)`trap handles calling a proxy as function:
505
+
La trappola `apply(target, thisArg, args)`gestisce l'invocazinone di un proxy come funzione:
506
506
507
-
-`target`is the target object (function is an object in JavaScript),
508
-
-`thisArg`is the value of`this`.
509
-
-`args`is a list of arguments.
507
+
-`target`è l'oggetto target (le funzioni sono oggetti in JavaScript),
508
+
-`thisArg`è il valore di`this`.
509
+
-`args`è la lista degli argomenti.
510
510
511
-
For example, let's recall`delay(f, ms)` decorator, that we did in the article<info:call-apply-decorators>.
511
+
Ad esempio, il decorator`delay(f, ms)`, che abbiamo sviluppato nell'articolo<info:call-apply-decorators>.
512
512
513
-
In that article we did it without proxies. A call to `delay(f, ms)`returned a function that forwards all calls to`f`after`ms`milliseconds.
513
+
In quell'articolo lo abbiamo fatto senza proxy. Un'invocazione di `delay(f, ms)`ritornava una funzione che inoltra le chiamate di`f`dopo`ms`millisecondi.
514
514
515
-
Here's the previous, function-based implementation:
515
+
Qui vediamo la precendente implementazione, basata sulla funzione:
516
516
517
517
```js run
518
518
functiondelay(f, ms) {
519
-
//return a wrapper that passes the call to f after the timeout
519
+
//ritorna un wrapper che invoca f dopo il timeout
520
520
returnfunction() { // (*)
521
521
setTimeout(() =>f.apply(this, arguments), ms);
522
522
};
@@ -526,15 +526,15 @@ function sayHi(user) {
526
526
alert(`Hello, ${user}!`);
527
527
}
528
528
529
-
//after this wrapping, calls to sayHi will be delayed for 3 seconds
529
+
//dopo il wrapping, le invocazion di sayHi verranno ritardate di 3 secondi
530
530
sayHi =delay(sayHi, 3000);
531
531
532
-
sayHi("John"); // Hello, John! (after 3 seconds)
532
+
sayHi("John"); // Hello, John! (dopo 3 secondi)
533
533
```
534
534
535
-
As we've seen already, that mostly works. The wrapper function `(*)`performs the call after the timeout.
535
+
Come abbiamo già visto, questo approccio funziona. La funzione wrapper `(*)`esegue l'invocazione dopo il timeout.
536
536
537
-
But a wrapper function does not forward property read/write operations or anything else. After the wrapping, the access is lost to properties of the original functions, such as `name`, `length`and others:
537
+
Ma una funzione wrapepr non esegue l'inoltro delle operazioni di lettura/scrittura o altro di simile. Dopo il wrapping, l'accesso alle proprietà della funzione originale è perso, come `name`, `length`e altri:
538
538
539
539
```js run
540
540
functiondelay(f, ms) {
@@ -548,19 +548,19 @@ function sayHi(user) {
548
548
}
549
549
550
550
*!*
551
-
alert(sayHi.length); // 1 (function length is the arguments count in its declaration)
551
+
alert(sayHi.length); // 1 (la lunghezza della funzione è il numero degli argomenti nella sua dichiarazione)
552
552
*/!*
553
553
554
554
sayHi =delay(sayHi, 3000);
555
555
556
556
*!*
557
-
alert(sayHi.length); // 0 (in the wrapper declaration, there are zero arguments)
557
+
alert(sayHi.length); // 0 (nella dichiarazione del wrapper, ci sono zero argomenti)
558
558
*/!*
559
559
```
560
560
561
-
`Proxy` is much more powerful, as it forwards everything to the target object.
561
+
Il `proxy` è molto più potente, poiché inoltra tutto all'oggeto target.
562
562
563
-
Let's use`Proxy`instead of a wrapping function:
563
+
Utiizziamo il`Proxy`piuttosto della funzione di wrapping:
564
564
565
565
```js run
566
566
functiondelay(f, ms) {
@@ -578,37 +578,37 @@ function sayHi(user) {
578
578
sayHi =delay(sayHi, 3000);
579
579
580
580
*!*
581
-
alert(sayHi.length); // 1 (*) proxy forwards "get length" operation to the target
The result is the same, but now not only calls, but all operations on the proxy are forwarded to the original function. So`sayHi.length`is returned correctly after the wrapping in the line`(*)`.
587
+
Il risultato è lo stesso, ma ora non viene inoltrata solamente l'invocazione, anche tutte le altre operazioni sul proxy vengono inoltrate alla funzione originale. Quindi`sayHi.length`viene ritornato correttamente dopo il wrapping alla riga`(*)`.
588
588
589
-
We've got a "richer" wrapper.
589
+
Abbiamo ottenuto un wrapper più "ricco".
590
590
591
-
Other traps exist: the full list is in the beginning of this article. Their usage pattern is similar to the above.
591
+
Esistono altre trappole: la lista completa la puoi trovare all'inizio di questo articolo. Il loro utilizzo è molto simile a quanto scritto sopra.
592
592
593
593
## Reflect
594
594
595
-
`Reflect`is a built-in object that simplifies creation of`Proxy`.
595
+
`Reflect`è un oggetto integrato che semplifica la creazione di`Proxy`.
596
596
597
-
It was said previously that internal methods, such as `[[Get]]`, `[[Set]]`and others are specification-only, they can't be called directly.
597
+
Come detto in precedenza, i metodi interni, come `[[Get]]`, `[[Set]]`e altri, esistono solamente nelle specifiche, non possono essere invocati direttamente.
598
598
599
-
The`Reflect`object makes that somewhat possible. Its methods are minimal wrappers around the internal methods.
599
+
L'oggetto`Reflect`lo rende in qualche modo possibile. I suoi metodi sono dei wrapper dei metodi interni.
600
600
601
-
Here are examples of operations and `Reflect`calls that do the same:
601
+
Qui vediamo degli esempi di operazioni e invocazioni di `Reflect`che fanno questo:
602
602
603
-
|Operation|`Reflect`call | Internal method|
603
+
|Operazione|invocazione `Reflect`| Metodo interno|
In particular, `Reflect`allows us to call operators (`new`, `delete`...) as functions (`Reflect.construct`, `Reflect.deleteProperty`, ...). That's an interesting capability, but here another thing is important.
621
+
In particolare, `Reflect`ci consente di invocare operatori (`new`, `delete`...) come funzioni (`Reflect.construct`, `Reflect.deleteProperty`, ...). Questa è una caratteristica interessante, ma qui vediamo un'altra cosa molto importante.
622
622
623
-
**For every internal method, trappable by `Proxy`, there's a corresponding method in `Reflect`, with the same name and arguments as the `Proxy` trap.**
623
+
**Per ogni metodo interno, a cui possiamo aggiungere una trappola con il `Proxy`, abbiamo un metodo corrispondente in `Reflect`, con lo stesso nome e gli stessi argomenti della trappola `Proxy`.**
624
624
625
-
So we can use `Reflect`to forward an operation to the original object.
625
+
Quindi possiamo utilizzare `Reflect`per inoltrare un operazione all'oggetto originale.
626
626
627
-
In this example, both traps `get`and`set`transparently (as if they didn't exist) forward reading/writing operations to the object, showing a message:
627
+
In questo esempio, entrambe le trappole `get`e`set`inoltrano in maniera trasparente (come se non esistessero) le operazioni di lettura/scrittura all'oggetto, mostrando il messaggio:
628
628
629
629
```js run
630
630
let user = {
@@ -646,26 +646,26 @@ user = new Proxy(user, {
646
646
}
647
647
});
648
648
649
-
let name =user.name; //shows "GET name"
650
-
user.name="Pete"; //shows "SET name=Pete"
649
+
let name =user.name; //mostra "GET name"
650
+
user.name="Pete"; //mostra "SET name=Pete"
651
651
```
652
652
653
-
Here:
653
+
Qui:
654
654
655
-
-`Reflect.get`reads an object property.
656
-
-`Reflect.set`writes an object property and returns `true`if successful, `false`otherwise.
655
+
-`Reflect.get`legge una proprietà di un oggetto.
656
+
-`Reflect.set`scrive una proprietà di un oggetto e ritorna `true`se quest avviene con succesos, `false`altrimenti.
657
657
658
-
That is, everything's simple: if a trap wants to forward the call to the object, it's enough to call `Reflect.<method>`with the same arguments.
658
+
Questo è tutto, piuttosto semplice: se una trappola vuole inoltrare l'invocazione all'oggetto, è sufficiente invocare `Reflect.<method>`con gli stessi argomenti.
659
659
660
-
In most cases we can do the same without`Reflect`, for instance, reading a property `Reflect.get(target, prop, receiver)`can be replaced by`target[prop]`. There are important nuances though.
660
+
In molti casi, possiamo ottenere lo stesso risultato senza`Reflect`, ad esempio, la lettura di una proprietà `Reflect.get(target, prop, receiver)`può essere sostituita da`target[prop]`. Ci sono però delle sfumature importanti.
661
661
662
-
### Proxying a getter
662
+
### Creare un proxy per un getter
663
663
664
-
Let's see an example that demonstrates why `Reflect.get`is better. And we'll also see why `get/set`have the third argument`receiver`, that we didn't use before.
664
+
Vediamo un esempio che dimostra perché `Reflect.get`è migliore. E vedremo anche perché `get/set`possiede il terzo argomento`receiver`, che non abbiamo utilizzato finora.
665
665
666
-
We have an object `user`with `_name`property and a getter for it.
666
+
Abbiamo un oggetto `user`con la proprietà `_name`ed il relativo getter.
667
667
668
-
Here's a proxy around it:
668
+
Costruiamo un proxy:
669
669
670
670
```js run
671
671
let user = {
@@ -686,11 +686,11 @@ let userProxy = new Proxy(user, {
686
686
alert(userProxy.name); // Guest
687
687
```
688
688
689
-
The `get`trap is "transparent" here, it returns the original property, and doesn't do anything else. That's enough for our example.
689
+
La trappola `get`è "trasparente" in questo caso, ritorna la proprietà originale, e non fa nient'altro. Questo è sufficiente per il nostro esempio.
690
690
691
-
Everything seems to be all right. But let's make the example a little bit more complex.
691
+
Tutto sembra funzionare correttamente. Ma rendiamo l'esempio leggermente più complesso.
692
692
693
-
After inheriting another object `admin`from`user`, we can observe the incorrect behavior:
693
+
Dopo aver ereditato con un oggetto `admin`da`user`, possiamo osservare un comportamento non corretto:
La lettura di `admin.name`dovrebbe ritornare`"Admin"`, non`"Guest"`!
721
721
722
-
What's the matter? Maybe we did something wrong with the inheritance?
722
+
Qual'è il problema? Magari abbiamo sbagliato qualcosa con l'ereditarietà?
723
723
724
-
But if we remove the proxy, then everything will work as expected.
724
+
Ma se rimuoviamo il proxy, tutto funziona correttamente.
725
725
726
-
The problem is actually in the proxy, in the line`(*)`.
726
+
Il problema sta quindi nel proxy, alla riga`(*)`.
727
727
728
-
1.When we read `admin.name`, as `admin`object doesn't have such own property, the search goes to its prototype.
729
-
2.The prototype is`userProxy`.
730
-
3.When reading `name`property from the proxy, its `get`trap triggers and returns it from the original object as `target[prop]`in the line`(*)`.
728
+
1.Quando leggiamo `admin.name`, poiché l'oggetto `admin`non possiede questa proprietà, la ricerca prosegue nel suo prototype.
729
+
2.Il prototype è`userProxy`.
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
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`.
0 commit comments