JavaScript proxy

Vždy jsem miloval flexibilitu objektů a prototypů v JavaScriptu, ale po dlouhou dobu jsem cítil, že chybí určitá úroveň dynamiky. JavaScript nakonec přidal get a set metody pro vlastnosti objektů, což byl úžasný krok, ale stále tu byl prostor pro zlepšení.

JavaScript Proxy API bylo úžasné vylepšení:virtualizační rozhraní pro řízení modifikačního chování objektu!

Formát proxy

Proxy přijímá objekt pro proxy a objekt s obslužnými rutinami ("pasti") pro get , set , has a další běžné objektové metody:

const proxy = new Proxy({}, {
  get: (obj, prop) => { ... },
  set: (obj, prop, value) => { ... },
  // more props here
});

Jakýkoli pokus o nastavení nebo získání vlastnosti je spuštěn přes past, což vám umožňuje spustit další logiku, zejména pokud je vlastnost nežádoucí, neexistuje nebo vyžaduje ověření.

Základní použití

Pojďme vytvořit základní proxy, která vrací výchozí hodnoty pro danou vlastnost:

const proxy = new Proxy({}, {
  get: (obj, prop) => {
    return prop in obj ? obj[prop] : null;
  }
});

// proxy.whatever => null

Výše uvedený příklad ukazuje, že bez ohledu na vlastnost, kterou se kód pokouší nastavit, vaše logika proxy ji může zachytit a upravit podle potřeby. Místo undefined je vrácena pro vlastnost, která neexistuje, můžete místo toho vrátit null .

Ověření

Nejviditelnější a nejužitečnější použití proxy je validace; protože monitorujete a ověřujete jakoukoli přicházející vlastnost, můžete udržovat svá data co nejčistší.

const proxy = new Proxy({}, { 
  set: (obj, prop, value) => {
    // Don't allow age > 100
    if (prop === "age" && value > 100) {
      // Set to max age
      value = 100;
    }
    obj[prop] = value;
  }
});

proxy.age = 120;
proxy.age; // 100

Můžete se rozhodnout upravit příchozí data jako v příkladu výše, nebo můžete vyvolat chybu:

const proxy = new Proxy({}, { 
  set: (obj, prop, value) => {
    // Ensure age is of type Number
    if (prop === "age" && isNaN(value)) {
      throw new Error("Invalid age value!");
      return;
    }
    obj[prop] = value;
  }
});

proxy.age = "yes";  // Uncaught error: Invalid age value!

Ladění

Proxy můžete dokonce použít k poskytování ladicích bodů nebo událostí, abyste viděli, jak a kdy se hodnoty nastavují a načítají:

const proxy = new Proxy({}, { 
  set: (obj, prop, value) => {
    console.log(`Setting ${prop} from ${obj[prop]} to ${value}`);
    obj[prop] = value;
  }
});

proxy.prop = 1;
proxy.prop = 2;

// Setting prop from undefined to 1
// Setting prop from 1 to 2

I když neupravíte žádný vstup nebo výstup, mít háček na změny hodnot na objektu je neuvěřitelně cenné.

Formátování

Dalším jednoduchým použitím je formátování dat, která přicházejí do objektu:

const proxy = new Proxy({}, { 
  set: (obj, prop, value) => {
    if (prop === "age") {
      obj[prop] = Number(value);
    }
  }
});

proxy.prop = "1"; // 1

Můžete formátovat z řetězce na číslo, z čísla na řetězec nebo jednoduše nastavit výchozí hodnoty.

Použití proxy s existujícími objekty

Ve výše uvedených příkladech používáme prázdný objekt ({} ), ale můžete také použít existující objekt:

const myObj = { x: "x", y: "y" };

// Use existing object, simply set value as is given
const proxy = new Proxy(myObj, { 
  set: (obj, prop, value) => { 
    obj[prop] = value; 
  } 
});

// 
proxy.x = "XXX";
proxy.x; // "XXX"
myObj.x; // "XXX"

Všimněte si, že původní objekt dělá změnit, stejně jako proxy, takže proxy není fungovat jako „kopie“, abych tak řekl.

Lidé rádi nenávidí PHP, ale jedna věc, kterou jsem na tomto jazyce miloval, byly "magické vlastnosti", které jste mohli špehovat a dynamicky na ně reagovat. Proxy API na to působí jako odpověď JavaScriptu. Čím více můžete kontrolovat, co přichází a odchází, tím lepší může být vaše aplikace!