This article is published simultaneously on Github personal blog: ES6 series Proxy

preface

A few days ago, I simulated the implementation of two MobX functions — MobX Observable and Autorun method, which use Proxy, so I plan to have a further understanding of Proxy and make notes.

Including the previous ES6 series, plus this should almost be the end of a series.

  • ES6 series let and const vs. VAR
  • ES6 series variable deconstruction assignment
  • ES6 series arrow functions fully resolved
  • ES6 series one of the text thoroughly understand Iterator
  • ES6 series arrow functions fully resolved
  • The ES6 series Generator Generator is fully analyzed
  • ES6 series Promise collection
  • ES6 Series handwritten Promise

What is the Proxy

Proxy objects are used to create a Proxy for an object to intercept and customize basic operations (such as property lookup, assignment, enumeration, function calls, and so on). A layer of “interception” is placed in front of the target object, through which all external access to the object must pass, thus providing a mechanism for filtering and overwriting external access.

const p = new Proxy(target, handler)

  • Target: A target object wrapped with a Proxy (which can be any type of JavaScript object, including a native array, a function, or even another Proxy).
  • Handler: An object, usually a function, used to customize interception behavior.

In proxy-enabled browser environments, Proxy is a global object that can be used directly. A Proxy(target, handler) is a constructor, target is the proxied object, and ultimately returns a Proxy object.

Why you need a Proxy

Before we learn something, we have to think about why we need it. In my opinion, there are usually several cases.

  1. Proxied objects do not want to be accessed directly
  2. Controls and modifies the behavior of proxied objects (calling properties, assigning properties, calling methods, and so on) so that they can perform access control and add functionality.

API

The API overview is as follows:

  • Get (target, propKey, receiver) : Intercepts reading of object properties, such as proxy.foo and proxy[‘foo’].
  • Set (target, propKey, value, receiver) : Intercepts the setting of object properties, such as proxy.foo = v or proxy[‘foo’] = v, and returns a Boolean value.
  • Has (target, propKey) : Intercepts the propKey in proxy operation and returns a Boolean value.
  • DeleteProperty (target, propKey) : Intercepts the operation of delete Proxy [propKey] and returns a Boolean value.
  • OwnKeys (target) : interception Object. GetOwnPropertyNames (proxy), Object. GetOwnPropertySymbols (proxy), the Object. The keys (proxy), for… The in loop returns an array. This method returns the property names of all of the target Object’s own properties, whereas object.keys () returns only the traversable properties of the target Object itself.
  • GetOwnPropertyDescriptor (target, propKey) : interception Object. GetOwnPropertyDescriptor (proxy, propKey), returns the attributes describe objects.
  • DefineProperty (target, propKey, propDesc) : Intercept Object. DefineProperty (proxy, propKey, propDesc),
  • Object.defineproperties (proxy, propDescs), which returns a Boolean value.
  • PreventExtensions (target) : Intercepts Object.preventExtensions(proxy), returns a Boolean.
  • GetPrototypeOf (target) : Intercepts object.getProtoTypeof (proxy) and returns an Object.
  • IsExtensible (Target) : Intercepts Object. IsExtensible (proxy), returning a Boolean value.
  • SetPrototypeOf (target, proto) : Intercepts Object.setPrototypeOf(proxy, proto) and returns a Boolean value. If the target object is a function, there are two additional operations that can be intercepted.
  • Apply (target, object, args) : intercepts operations called by Proxy instances as functions, such as Proxy (… The args), proxy. Call (object,… The args), proxy. Apply (…). `.
  • Construct (target, args) : intercepts operations called by Proxy instances as constructors, such as new Proxy (… The args).

The most common methods are get and set

example

get

const target = {
  name: 'jacky'.sex: 'man',}const handler = {
  get(target, key) {
    console.log('Get name/Gender')
    return Reflect.get(target, key)
  },
}
const proxy = new Proxy(target, handler)
console.log(proxy.name)
Copy the code

Run, printable output:

Get the name/gender JackyCopy the code

Get (target, key); / / Reflect. Get (target, key); / / Reflect.

set

const target = {
  name: 'jacky'.sex: 'man',}const handler = {
  get(target, key) {
    console.log('Get name/Gender')
    return Reflect.get(target, key)
  },
  set(target, key, value) {
    return Reflect.set(target, key, 'forcibly set to${value}`)}},const proxy = new Proxy(target, handler)
proxy.name = 'monkey'
console.log(proxy.name)
Copy the code

Run output:

Get the name/gender to force the monkeyCopy the code

Setting proxy.name = ‘monkey’, which is to change the value of the property, triggers the set method, and then we forcibly change the value and return to intercept the setting of the property of the object.


Reflect objects, like Proxy objects, are a new API provided by ES6 for manipulating objects. Reflect.get(target, name, receiver) : Finds and returns the name property of the target object, or undefined if it does not exist. Reflect.set(target, name, value, receiver) : Sets the name property of the target object to value.Copy the code

This points to the

The proxy changes the this pointer in target, and once the proxy proxies the target, this inside the target points to the proxy

const target = new Date('2021-01-03')
const handler = {}
const proxy = new Proxy(target, handler)

console.log(proxy.getDate())
Copy the code

TypeError: this is not a Date object. TypeError: this is not a Date object. TypeError: this is not a Date object.

const target = new Date('2021-01-03')
const handler = {
  get(target, prop) {
    if (prop === 'getDate') {
      return target.getDate.bind(target) / / binding
    }
    return Reflect.get(target, prop)
  },
}
const proxy = new Proxy(target, handler)

console.log(proxy.getDate()) / / 3
Copy the code

Application scenarios

  • Warning or blocking specific actions
  • If the get method doesn’t get a value, it can return whatever value we want to specify
  • Data verification. Determine whether the data meets the conditions

And so on…

reference

  • es6.ruanyifeng.com/#docs/proxy


Ps:

  • Personal tech blog Github repository

If you feel good, give me a star, give me the motivation to continue to create!