Come funzionano gli oggetti proxy in JavaScript?

Come funzionano gli oggetti proxy in JavaScript?

Un oggetto proxy JavaScript consente di intercettare e personalizzare il comportamento di un altro oggetto, senza modificare l’originale.

Utilizzando gli oggetti proxy, puoi convalidare i dati, fornire funzionalità extra e controllare l’accesso a proprietà e funzioni.

Scopri tutto sugli usi degli oggetti proxy e su come crearli in JavaScript.

Creazione di un oggetto proxy

In JavaScript, puoi creare oggetti proxy utilizzando il costruttore Proxy . Questo costruttore accetta due argomenti: un oggetto target per avvolgere il proxy e un oggetto gestore le cui proprietà definiscono il comportamento del proxy quando si eseguono operazioni.

Prende questi argomenti e crea un oggetto che puoi usare al posto dell’oggetto di destinazione. Questo oggetto creato può ridefinire le operazioni principali come il recupero, l’impostazione e la definizione delle proprietà. È inoltre possibile utilizzare questi oggetti proxy per registrare gli accessi alle proprietà e convalidare, formattare o disinfettare gli input.

Per esempio:

const originalObject = {
  foo: "bar"
}

const handler = {
  get: function(target, property) {
    return target[property];
  },
  set: function(target, property, value) {
    target[property] = value;
  }
};


const proxy = new Proxy(originalObject, handler)

Questo codice crea un oggetto di destinazione, originalObject , con una singola proprietà, foo e un oggetto gestore, handler . L’oggetto gestore contiene due proprietà, get e set . Queste proprietà sono note come trap.

Un trap oggetto proxy è una funzione chiamata ogni volta che si esegue un’azione specificata su un oggetto proxy. Le trap consentono di intercettare e personalizzare il comportamento dell’oggetto proxy. L’accesso a una proprietà dall’oggetto proxy chiama get trap e la modifica o la manipolazione di una proprietà dall’oggetto proxy chiama set trap.

Infine, il codice crea un oggetto proxy con il costruttore Proxy . Passa originalObject e handler rispettivamente come oggetto e gestore di destinazione.

Utilizzo di oggetti proxy

Gli oggetti proxy hanno diversi usi in JavaScript, alcuni dei quali sono i seguenti.

Aggiunta di funzionalità a un oggetto

È possibile utilizzare un oggetto proxy per eseguire il wrapping di un oggetto esistente e aggiungere nuove funzionalità, come la registrazione o la gestione degli errori, senza modificare l’oggetto originale.

Per aggiungere nuove funzionalità, dovrai utilizzare il costruttore Proxy e definire uno o più trap per le azioni che vuoi intercettare.

Per esempio:

const userObject = {
  firstName: "Kennedy",
  lastName: "Martins",
  age: 20,
};

const handler = {
  get: function (target, property) {
    console.log(`Getting property "${property}"`);
    return target[property];
  },
  set: function (target, property, value) {
    console.log(`Setting property "${property}"to value "${value}"`);
    target[property] = value;
  },
};

const proxy = new Proxy(userObject, handler);

console.log(proxy.firstName); // Getting property "firstName"Kennedy
console.log(proxy.lastName); // Getting property "lastName"Martins
proxy.age = 23; // Setting property "age" to value "23"

Questo blocco di codice aggiunge funzionalità tramite trap proxy, get e set . Ora, quando si tenta di accedere o modificare una proprietà di userObject , l’oggetto proxy registrerà prima l’operazione nella console prima di accedere o modificare la proprietà.

Convalida dei dati prima di impostarli su un oggetto

È possibile utilizzare oggetti proxy per convalidare i dati e assicurarsi che soddisfino determinati criteri prima di impostarli su un oggetto. Puoi farlo definendo la logica di convalida in un set trap nell’oggetto gestore .

Per esempio:

const userObject = {
  firstName: "Kennedy",
  lastName: "Martins",
  age: 20,
};

const handler = {
  get: function (target, property) {
    console.log(`Getting property "${property}"`);
    return target[property];
  },
  set: function (target, property, value) {
    if (
      property === "age" &&
      typeof value == "number" &&
      value > 0 &&
      value < 120
    ) {
      console.log(`Setting property "${property}"to value "${value}"`);
      target[property] = value;
    } else {
      throw new Error("Invalid parameter. Please review and correct.");
    }
  },
};


const proxy = new Proxy(userObject, handler);
proxy.age = 21;

Questo blocco di codice aggiunge regole di convalida al set trap. Puoi assegnare qualsiasi valore alla proprietà age su un’istanza userObject . Tuttavia, con le regole di convalida aggiunte, puoi assegnare un nuovo valore alla proprietà age solo se è un numero, maggiore di 0 e minore di 120. Qualsiasi valore che cerchi di impostare sulla proprietà age che non soddisfa i criteri richiesti attiverà un errore e stamperà un messaggio di errore.

Controllo dell’accesso alle proprietà degli oggetti

È possibile utilizzare oggetti proxy per nascondere determinate proprietà di un oggetto. A tale scopo, definire la logica di restrizione in get trap per le proprietà a cui si desidera controllare l’accesso.

Per esempio:

const userObject = {
  firstName: "Kennedy",
  lastName: "Martins",
  age: 20,
  phone: 1234567890,
  email: "foo@bar.com",
};

const handler = {
  get: function (target, property) {
    if (property === "phone" || property === "email") {
      throw new Error("Access to info denied");
    } else {
      console.log(`Getting property "${property}"`);
      return target[property];
    }
  },
  set: function (target, property, value) {
    console.log(`Setting property "${property}"to value "${value}"`);
    target[property] = value;
  },
};

const proxy = new Proxy(userObject, handler);

console.log(proxy.firstName); // Getting property "firstName"Kennedy
console.log(proxy.email); // Throws error

Il blocco di codice sopra aggiunge alcune restrizioni al get trap. Inizialmente, puoi accedere a tutte le proprietà disponibili su userObject . Le regole aggiunte impediscono l’accesso a informazioni sensibili come l’e-mail o il telefono dell’utente. Il tentativo di accedere a una di queste proprietà attiverà un errore.

Altre trappole proxy

Le trap get e set sono le più comuni e utili, ma ci sono altre 11 trap proxy JavaScript. Sono:

  • apply : Il trap apply viene eseguito quando si chiama una funzione sull’oggetto proxy.
  • costrutto : il costrutto trap viene eseguito quando si utilizza l’operatore new per creare un oggetto dall’oggetto proxy.
  • deleteProperty : il trap deleteProperty viene eseguito quando si utilizza l’ operatore delete per rimuovere una proprietà dall’oggetto proxy.
  • has : has trap viene eseguito quando si utilizza l’ operatore in per verificare se esiste una proprietà sull’oggetto proxy.
  • ownKeys – Il trap ownKeys viene eseguito quando si chiama la funzione Object.getOwnPropertyNames o Object.getOwnPropertySymbols sull’oggetto proxy.
  • getOwnPropertyDescriptor – Il trap getOwnPropertyDescriptor viene eseguito quando si chiama la funzione Object.getOwnPropertyDescriptor sull’oggetto proxy.
  • defineProperty – Il trap defineProperty viene eseguito quando si chiama la funzione Object.defineProperty sull’oggetto proxy.
  • preventExtensions – Il trap preventExtensions viene eseguito quando si chiama la funzione Object.preventExtensions sull’oggetto proxy.
  • isExtensible – La trap isExtensible viene eseguita quando si chiama la funzione Object.isExtensible sull’oggetto proxy.
  • getPrototypeOf – Il trap getPrototypeOf viene eseguito quando si chiama la funzione Object.getPrototypeOf sull’oggetto proxy.
  • setPrototypeOf – La trap setPrototypeOf viene eseguita quando si chiama la funzione Object.setPrototypeOf sull’oggetto proxy.

Come i trap imposta e ottieni , puoi utilizzare questi trap per aggiungere nuovi livelli di funzionalità, convalida e controllo al tuo oggetto senza modificare l’originale.

I contro degli oggetti proxy

Gli oggetti proxy possono essere un potente strumento per aggiungere funzionalità personalizzate o convalida a un oggetto. Ma hanno anche alcuni potenziali svantaggi. Uno di questi inconvenienti è la difficoltà di debug, poiché può essere difficile vedere cosa sta succedendo dietro le quinte.

Anche gli oggetti proxy possono essere difficili da usare, specialmente se non li conosci. Dovresti considerare attentamente questi inconvenienti prima di usare oggetti proxy nel tuo codice.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *