# JavaScript Proxy Objects

> Learn how to use JavaScript Proxy objects to intercept and change how an object behaves, defining traps like get, set and deleteProperty in a handler.

Author: [Flavio Copes](https://flaviocopes.com/about/) | Published: 2020-06-23 | Topics: [JavaScript](https://flaviocopes.com/tags/js/) | Canonical: https://flaviocopes.com/javascript-proxy-objects/

When working with objects, we can create a **proxy object** that intercepts and changes the behavior of an existing object.

We do so using the **Proxy** native object, introduced in ES2015.

Suppose we have a `car` object:

```js
const car = {
  color: 'blue'
}
```

A very simple example we can make is to return a 'Not found' string when we try to access a property that does not exist.

You can define a proxy that is called whenever you try to access a property of this object.

You do so by creating another object that has a `get()` method, which receives the target object and the property as parameters:

```js
const car = {
  color: 'blue'
}

const handler = {
  get(target, property) {
    return target[property] ?? 'Not found'
  }
}
```

Now we can initialize our proxy object by calling `new Proxy()`, passing the original object, and our handler:

```js  
const proxyObject = new Proxy(car, handler)
```

Now try accessing a property contained in the `car` object, but referencing it from `proxyObject`:

```js
proxyObject.color //'blue'
```

This is just like calling `car.color`.

But when you try to access a property that does not exist on `car`, like `car.test`, you'd get back `undefined`. Using the proxy, you will get back the `'Not found'` string, since that's what we told it to do.

```js
proxyObject.test //'Not found'
```

We're not limited to the `get()` method in a proxy handler. That was just the simplest example we could write.

We have other methods we can use:

- `apply` is called when we use `apply()` on the object
- `construct` is called when we access the object constructor
- `deleteProperty` is executed when we try to delete a property
- `defineProperty` is called when we define a new property on the object
- `set` is executed when we try to set a property

and so on. Basically we can create a guarded gate that controls everything that happens on an object, and provide additional rules and controls to implement our own logic.

Other methods (also called *traps*) we can use are:

- `enumerate`
- `getOwnPropertyDescriptor`
- `getPrototypeOf`
- `has`
- `isExtensible`
- `ownKeys`
- `preventExtensions`
- `setPrototypeOf`

all corresponding to the respective functionality.

You can [read more about each of those on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/Proxy).

Let's make another example using `deleteProperty`. We want to prevent deleting properties of an object:

```js
const car = {
  color: 'blue'
}

const handler = {
  deleteProperty(target, property) {
    return false
  }
}

const proxyObject = new Proxy(car, handler)
```

If we call `delete proxyObject.color`, we'll get a TypeError:

```
TypeError: 'deleteProperty' on proxy: trap returned falsish for property 'color'
```

Of course one could always delete the property directly on the `car` object, but if you write your logic so that that object is inaccessible and you only expose the proxy, that is a way to encapsulate your logic.
