Using javascript proxy
Tags: javascript, proxy
Published: 2020-01-15 15:49:57

---
title: Using javascript proxy
published: true
description: 
tags: javascript, proxy
---

I have recently been digging into proxy in Javascript. I was surprised by what it can do. **Proxy** allows you to hook into fundamental operations of the language constructs (like object, arrays, functions..)

Here is list of simple usecases for javascript proxy

### Freezing Object

We can prevent mutation of objects easily with few lines of code essentially freezing the object

 ```javascript
 const hero = {
   name: 'Saitama',
   age: 25,
   class: 'B',
   race: 'Human',
   heroName: 'Caped Baldy',
 };

 const Freeze = obj =>
   new Proxy(obj, {
     set: function(target, key, value) {
       throw Error("You can't change values this object has been frozen");
     },
   });

 const saitama = Freeze(hero);
 saitama.name = 'Garuro';   // This will throw error
 ```

You can also freeze arrays, Map, WeakMap, Set...


### Tracking changes on object

Proxy can be used track changes to object essentially maintain history.

 ```javascript
 const createHistory = obj => {
   let history = [JSON.parse(JSON.stringify(obj))];
   const proxiedObject = new Proxy(obj, {
     set: function(target, key, value) {
       history.push({ ...target, [key]: value });
       Reflect.set(target, key, value);
     },
   });
   return [history, proxiedObject];
 };

 const [history, proxiedObject] = createHistory(hero);
 proxiedObject.name = 'Genos';
 proxiedObject.class = 'C';

 console.log(history);
 ```

history object will contains snapshot of changes made to the object  
 ```javascript
 [
   {
     name: 'Saitama',
     age: 25,
     class: 'B',
     race: 'Human',
     heroName: 'Caped Baldy'
   },
   {
     name: 'Genos',
     age: 25,
     class: 'B',
     race: 'Human',
     heroName: 'Caped Baldy'
   },
   {
     name: 'Genos',
     age: 25,
     class: 'C',
     race: 'Human',
     heroName: 'Caped Baldy'
   }
 ]
 ```

similarly you can also track number of times function was called with apply trigger.

### Case insensitive key access

 ```javascript
 const caseInsensitive = obj =>
   new Proxy(obj, {
     get: function(target, key) {
       // I am assuming keys are lowercase by default for simplicity
       return Reflect.get(target, key.toLowerCase());
     },
   });

 const proxiedObject = caseInsensitive(hero);
 console.log(proxiedObject.name); // saitama
 console.log(proxiedObject.NAME); // saitama
 ```

### Handling properties that does not exist

You can easily handle undefined properties by following snippet

 ```javascript
 const FetchValue = obj =>
   new Proxy(obj, {
     get: function(target, key) {
       if (target.hasOwnProperty(key)) {
         return [Reflect.get(target, key), true];
       }
       return [null, false];
     },
   });


 const proxiedObject = FetchValue(hero);

 const [name, nameExist] = proxiedObject.name;
 const [city, cityExist] = proxiedObject.city;

 if (nameExist) {
   console.log(name);
 }

 if (cityExist) {
   console.log(city); // this is not executed since property city does not exist
 }
 ```



You can do much more with proxy than what is listed here. You can look up more awesome usage here https://github.com/mikaelbr/awesome-es2015-proxy