# JS Tip of the Day: Proxy Objects

**URL:** <https://forum.kirupa.com/t/js-tip-of-the-day-proxy-objects/643118>\
**Category:** web dev\
**Created:** [April 18, 2020, 1:28pm UTC](https://forum.kirupa.com/t/js-tip-of-the-day-proxy-objects/643118 "2020-04-18T13:28:53Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![senocular](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/senocular/32/7217_2.png) [@senocular](https://forum.kirupa.com/u/senocular)\
**Post date:** [April 18, 2020, 1:28pm UTC](https://forum.kirupa.com/t/js-tip-of-the-day-proxy-objects/643118/1 "2020-04-18T13:28:53Z")

</div>

**Proxy Objects**  
Version: ES2015  
Level: Advanced

Proxy objects are exotic objects that transparently wrap other objects providing a method for intercepting operations like property access or assignment. In doing this, they can provide functionality that is not possible with normal JavaScript objects.

To create a Proxy object, you would use the `Proxy` constructor, passing in the object to be wrapped followed by a handler object which defines all of the operations that are to be intercepted. The definitions in the handler are known as traps.

```javascript
let gift = { value: 'Holiday 6 Pack' };
let wrapped = new Proxy(gift, { /* add traps here */ });
console.log(wrapped.value); // Holiday 6 Pack

```

In the example above, `wrapped` is the proxy version of the `gift` object. Because the handler is empty (`{}`), having no traps, it will appear in every way like the original gift object.

In fact there’s no observable way to tell that a proxy object is not the original wrapped object unless you compared them to each other directly. Even checks like `instanceof` will continue to work as though acting on the original object because it goes _through_ the proxy rather than acting on it.

```javascript
let date = new Date();
let wrapped = new Proxy(date, {});
console.log(wrapped instanceof Date); // true
console.log(wrapped instanceof Proxy); // Error

```

By defining a trap in the handler we can add additional behavior to the wrapped object. A common trap is the `get` trap that is used to intercept property access. The can be used to change the result of what happens when you access the `value` property in the proxy version of the `gift` object.

```javascript
let gift = { value: 'Holiday 6 Pack' };
let wrapped = new Proxy(gift, {
    get (target, property, receiver) {
        let value = Reflect.get(target, property, receiver);
        if (property === 'value') {
            return value.replace('6', '5'); // altered value
        }
        return value; // original value
    }
});
console.log(wrapped.value); // Holiday 5 Pack

```

Here, the original value is obtained through `Reflect.get()` (from the wrapped `gift` object) and if the name of that property is `'value'`, the result is altered changing instances of ‘6’ to ‘5’. Other properties behave normally returning the same value as they would if there were no proxy.

While the above behavior can also be achieved with a getter in an accessor property, what accessors can’t do that proxies can is intercept properties that don’t yet exist. With of this, you could create an array-like behavior that automatically updates a `length` property when new indexed values are set - something which would not be possible with accessor properties alone.

```javascript
let fakeArray = new Proxy({ length: 0 }, {
    set (target, property, value, receiver) {
        let newLength = Number(property) + 1;
        let length = Reflect.get(target, 'length', receiver);
        if (newLength > length) {
            Reflect.set(target, 'length', newLength, receiver);
        }
        return Reflect.set(target, property, value, receiver);
    }
});
console.log(fakeArray.length); // 0
fakeArray[0] = 'a';
console.log(fakeArray.length); // 1
fakeArray[4] = 'e';
console.log(fakeArray.length); // 5

```

Traps exist for many other operations include property defining (not just assigning), function calling, getting object keys, and many more. See the MDN link below for the additional traps you can define for a proxy.

More info:

- [Proxy on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy)
- [Reflect.get on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/get)
- [Reflect.set on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/set)
- [Holiday 5 Pack on Youtube](https://www.youtube.com/watch?v=mZM8mGJMAcU)
