//

PROXIES

Proxies enable you to intercept and customize actions performed on JavaScript objects such as `getter` and `setter` for getting and setting properties. This is really helpful in scenarios like JSON based API interaction where you have to customize data coming back from the API.

They introduce intercession to JavaScript, which is a type of meta programming.

Meta Programming

In programming there different levels, base level which perform user input and meta level which processes base level code. An example is eval() which compiles JavaScript code, which itself is JavaScript. But you can use two different languages for base level and meta level. Or just JavaScript.

Creating a proxy on a particular object allows a predefined handler to get notified when something changes on that object.

Proxies are created with two parameters handler and target.

  • handler - Intercepts the operation on the way to target.
  • target - If the handler doesn't intercept an operation then it's performed on the target.
// Proxying a normal object
var target = {};
var handler = {
  get: function (receiver, name) {
    return 'Hello, ' + name;
  }
};

var p = new Proxy(target, handler);
p.world === "Hello, world!";

// Proxying a function object
var target = function () { return "I am the target"; };
var handler = {
  apply: function (receiver, ...args) {
    return "I am the proxy";
  }
};

var p = new Proxy(target, handler);
p() === "I am the proxy";

Methods of handler object

The handler object is a placeholder object which contains traps for Proxy.

Traps

All traps are optional. If a trap has not been defined, the default behavior is to forward the operation to the target.

Here are the methods of handler object:

  • getPrototypeOf()
  • setPrototypeOf()
  • isExtensible()
  • preventExtensions()
  • getOwnPropertyDescriptor()
  • defineProperty()
  • has()
  • get()
  • set()
  • deleteProperty()
  • enumerate()
  • ownKeys()
  • apply()
  • apply()

Here's another example that sets a property using proxy.

var student = { name: 'John Smith', age: 16 };

var interceptor = {
  set: function (receiver, property, value) {
    console.log(property, 'is changed to', value);
    receiver[property] = value;
  }
};

student = Proxy(student, interceptor);

student.age = 17; // age is changed to 17

Here the intercepter is the handler, which is the second parameter. The student object has been replaced by the another one as the result of installing proxy via Proxy()

Beside for debugging purposes, proxy can be helpful for libraries which implement data binding. Because a handler can be hooked to the data model, there is no need to use an alternative syntax (e.g. explicit set to change a value) or to continuously track the change (e.g. dirty state) to modify the model.