# Getting Started with Modern JavaScript — Proxy

JavaScript proxies were introduced in 2015 with ECMAScript 6\. They allow us to **intercept** and **override** operations such as object property lookup and assignment. A `Proxy` object wraps another object and acts as a middleman.

![proxy.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1601032063441/DtWE_RD6Q.png)

# Syntax

A proxy is created using the `new Proxy` constructor with two required arguments: the **target** and the **handler**.

```js
let proxy = new Proxy(target, handler)</span>
```

*   `target` — The object we wrap.
*   `handler` — An object that defines the methods (also called **traps**) to control the behaviors of the _target_.

A `Proxy` creates an undetectable barrier around the target object that redirects all operations to the handler object. If we send in an empty `handler`, the proxy is just an empty wrapper around the original object.

```js
let user = { 
  name: 'Max', 
  age: 42
};

let proxyUser = new Proxy(user, {});

console.log(user.name); // -> Max
console.log(proxyUser.name); // -> Max
```

To give the proxy meaning, we need to add some functionality to the handler.

# Traps

Whenever you interact with an object, you are calling an internal method. Proxies allow you to intercept the execution of a given internal method with traps.

So when we run `user.name` we are telling the JavaScript engine to call the internal `[[GET]]` method to retrieve the `name` property.

When we run `proxyUser.name` the **get trap** calls the `get()` function defined in the `handler` to execute before sending the call through to the original object.

![proxyuser.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1601032501769/aPsFfmRBc.png)

## Get

The `get()` method has two required parameters:

*   `target` — Object passed to the proxy.
*   `property` — Name of the accessed property.

To customize the proxy, we define functions on the `handler` object. Here we define the `get` method to log the access:

```js
const handler = {
  get(target, property) {
    console.log(`GET ${property}`);
    return target[property];
  }
};
```

To let the call through, we return `target[property]`.

Now, if we create a proxy with this handler and try to access the original object, we log the call:

```js
const proxyUser = new Proxy(user, handler);
 
console.log(proxyUser.age);
// -> GET age
// -> 42
```

We can see that when we access a property of the `user` object via the `proxyUser` object, the `get()` method fires in the `handler` object.

## Set

The **set trap** controls behavior when a property of the `target` object is assigned.

Let’s validate the input of the `age` value:

```js
const handler = {
  set(target, property, value) {
    if(property === 'age' && typeof(value) !== 'number') {
      throw new TypeError('Age is just a number.');
    }
 
    target[property] = value;
    return true;
  }
}
```

If we try to assign a wrong type to `age` an error is thrown:

```js
proxyUser.age = 'old';
// -> TypeError: Age is just a number.
```

In the line `target[property] = value` we set the `age` property of the `user` object.

The `set()` method should return a boolean value `true` to indicate that the assignment succeeded. If the JavaScript is run in _strict mode_, and a _falsy_ value or nothing is returned, an error will be thrown.

```js
Uncaught TypeError: ‘set’ on proxy: trap returned falsish for property 'age'
```

> In addition to intercepting reads and modifications to properties, Proxy can intercept a total of 13 operations.

# Conclusion

We have learned how we can use a proxy to spy on objects. You should now be able to add behaviors to them by using trap methods in the handler object. We have only dipped our toes into proxies with a couple of basic examples but it’s enough to get started and inspired to explore the possibilities!

%[https://www.educative.io/courses/game-development-js-tetris]


