Getting Started with Modern JavaScript — Proxy

Post Editor

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.

3 min read
post

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.

post
post
3 min read
3 min read

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

Syntax

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

let proxy = new Proxy(target, handler);
  • 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.

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

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:

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:

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:

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 the wrong type to age, an error is thrown:

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.

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 just dipped our toes into proxies with a couple of basic examples, but it’s enough to get started and inspired to explore the possibilities!

Discuss with community

Share

About the author

author_image

Angular by day. React by night. Full-stack when needed. I like blogging about web stuff. Co-organizer ngVikings.

author_image

About the author

Michael Karén

Angular by day. React by night. Full-stack when needed. I like blogging about web stuff. Co-organizer ngVikings.

About the author

author_image

Angular by day. React by night. Full-stack when needed. I like blogging about web stuff. Co-organizer ngVikings.

NxAngularCli
NxAngularCli
NxAngularCli

Featured articles

Angularpost
4 March 20218 min read
Angular Universal: real app problems

Angular Universal is an open-source project that extends the functionality of @angular/platform-server. The project makes server-side rendering possible in Angular. This article will discuss the issues and possible solutions we encountered while developing a real application with Angular Universal.

Angularpost
4 March 20218 min read
Angular Universal: real app problems

Angular Universal is an open-source project that extends the functionality of @angular/platform-server. The project makes server-side rendering possible in Angular. This article will discuss the issues and possible solutions we encountered while developing a real application with Angular Universal.

Read more
AngularpostAngular Universal: real app problems

4 March 2021

8 min read

Angular Universal is an open-source project that extends the functionality of @angular/platform-server. The project makes server-side rendering possible in Angular. This article will discuss the issues and possible solutions we encountered while developing a real application with Angular Universal.

Read more
Angularpost
3 March 20215 min read
View State Selector  - Angular design pattern

As a web developer you may have noticed a repetitive boiler plate code of displaying a loader while an asynchronous request is being processed, then switching to the main view or displaying an error. Personally, I noticed these repetitions both in my code and other developers I work with. And even worse than the repetitive code is the fact that there are no indications for missing state views (such as unhandled errors or a missing loader). <div *ngIf="data$ | async as data"> <ng-container *ng

Angularpost
3 March 20215 min read
View State Selector  - Angular design pattern

As a web developer you may have noticed a repetitive boiler plate code of displaying a loader while an asynchronous request is being processed, then switching to the main view or displaying an error. Personally, I noticed these repetitions both in my code and other developers I work with. And even worse than the repetitive code is the fact that there are no indications for missing state views (such as unhandled errors or a missing loader). <div *ngIf="data$ | async as data"> <ng-container *ng

Read more
AngularpostView State Selector  - Angular design pattern

3 March 2021

5 min read

As a web developer you may have noticed a repetitive boiler plate code of displaying a loader while an asynchronous request is being processed, then switching to the main view or displaying an error. Personally, I noticed these repetitions both in my code and other developers I work with. And even worse than the repetitive code is the fact that there are no indications for missing state views (such as unhandled errors or a missing loader). <div *ngIf="data$ | async as data"> <ng-container *ng

Read more
RxJSpost
26 February 20213 min read
RxJS: Why memory leaks occur when using a Subject

It's not uncommon to see the words 'unsubscribe', 'memory leaks', 'subject' in the same phrase when reading upon RxJS-related materials. In this article, we're going to tackle this fact and by the end of it you should gain a better insight as to why memory leaks occur.

RxJSpost
26 February 20213 min read
RxJS: Why memory leaks occur when using a Subject

It's not uncommon to see the words 'unsubscribe', 'memory leaks', 'subject' in the same phrase when reading upon RxJS-related materials. In this article, we're going to tackle this fact and by the end of it you should gain a better insight as to why memory leaks occur.

Read more
RxJSpostRxJS: Why memory leaks occur when using a Subject

26 February 2021

3 min read

It's not uncommon to see the words 'unsubscribe', 'memory leaks', 'subject' in the same phrase when reading upon RxJS-related materials. In this article, we're going to tackle this fact and by the end of it you should gain a better insight as to why memory leaks occur.

Read more