头图

foreword

Proxy can be understood as setting up a layer of "interception" before the target object, and access to the object from the outside world must pass this layer of interception first, so it provides a mechanism to filter and rewrite the access to the outside world. The original meaning of the word Proxy is a proxy, and it is used here to indicate that it is used to "proxy" some operations, which can be translated as "proxy".

grammar

var proxy = new Proxy(target, handler);

All uses of the Proxy object are in the form above, the only difference is the way the handler parameter is written. in:

  • new Proxy() means generating a Proxy instance
  • The target parameter indicates the target object to be intercepted
  • The handler parameter is also an object used to customize the interception behavior

If the handler does not set any interception, it is equivalent to direct access to the original object.

let target = {};
let handler = {};
let proxy = new Proxy(target,handler);
proxy.name = '编程三昧'; 
console.log(target.name); // '编程三昧'

Another trick is to set the Proxy object to the object.proxy property and call on the object object:

let proxy = new Proxy({}, {
  get: function(target, property) {
    return 35;
  }
});

let obj = Object.create(proxy);
obj.time // 35

get()

The get() method is used to intercept the read operation of a property and can accept three parameters, which are:

  • target
  • property name
  • The proxy instance itself (strictly speaking, the object on which the action is performed), optional.

get() is already an example of the usage of the 061f9590cbeb04 method. Here is another example of intercepting the read operation:

let  perosn = {
    name:'james',
    age:26,
    profession:'software'
}

var proxy = new Proxy(perosn,{
    get:function(target,property) {
        if (property in target) {
            return target[property];
        } else {
            throw new ReferenceError("propertype\""+property + "\" does no exit" );
        }
    }
});

console.log(proxy.name,proxy.profession); // james software
console.log(proxy.sex); // Uncaught ReferenceError: propertype"sex" does no exit

set()

set() method is used to intercept the assignment operation of an attribute, and can accept four parameters, in order:

  • target
  • property name
  • attribute value
  • The Proxy instance itself, optional.

Assuming that the person object has an age attribute, which should be an integer not greater than 200, then Proxy can be used to ensure that the age attribute value meets the requirements.

let perosn = {
    name:'james',
    age:26,
    profession:'software'
}

let proxy = new Proxy(perosn,{
    get:function(target,property) {
        if (property in target) {
            return target[property];
        } else {
            throw new ReferenceError("propertype\""+property + "\" does no exit" );
        }
    },
    set:function(target,key,value) {
        if(key === 'age') {
            if(value>80) {
                throw ReferenceError("invail");
            } else {
                return target[key] = value;
            }
        } else {
            return target[key];
        }
    }
});
proxy.age = 60;
console.log(proxy.name,proxy.profession,proxy.age); // james software 60

proxy.age = 99; // Uncaught ReferenceError: invail

apply()

apply() method interception:

  • function call
  • call operation
  • apply operation

apply() method can accept three parameters, namely:

  • target
  • The context object of the target object (this)
  • The parameter array of the target object.
let twice = {
    apply(target, ctx, agrs) {
        return Reflect.apply(...arguments) * 2;
    }
};
function sum (a, b) {
    return a + b;
}
let proxy5 = new Proxy(sum, twice);

console.log(proxy5(1, 3));  // 8
console.log(proxy5.apply(null, [1, 3])); // 8

In addition, calling the Reflect.apply method directly will also be intercepted.

Reflect.apply(proxy5, null, [9, 10]) // 38

has()

has() method is used to intercept the HasProperty operation, that is, when it is judged whether the object has a certain property, this method will take effect. A typical operation is the in operator.

has() method can accept two parameters, which are the target object and the property name to be queried.

The following example uses the has method to hide certain properties from the in operator.

let stu1 = {name: '张三', score: 59};
let stu2 = {name: '李四', score: 99};

let handler = {
  has(target, prop) {
    if (prop === 'score' && target[prop] < 60) {
      console.log(`${target.name} 不及格`);
      return false;
    }
    return prop in target;
  }
}

let oproxy1 = new Proxy(stu1, handler);
let oproxy2 = new Proxy(stu2, handler);

'score' in oproxy1
// 张三 不及格
// false

'score' in oproxy2
// true

for (let a in oproxy1) {
  console.log(oproxy1[a]);
}
// 张三
// 59

for (let b in oproxy2) {
  console.log(oproxy2[b]);
}
// 李四
// 99

In the above code, the has interception is only valid for the in operator, for...in loop, so that the properties that do not meet the requirements are not excluded by the for...in loop.

List of interception operations supported by Proxy

There are basically 13 interception operations supported by Proxy.

get(target, propKey, receiver)

Intercept the reading of object properties, such as:

  • proxy.foo
  • proxy['foo']

set(target, propKey, value, receiver)

Intercept object property settings, such as proxy.foo = v or proxy['foo'] = v , return a boolean value.

has(target, propKey)

Intercept propKey in proxy and return a boolean value.

deleteProperty(target, propKey)

Intercept delete proxy[propKey] and return a boolean value.

ownKeys(target)

Intercept:

  • Object.getOwnPropertyNames(proxy)
  • Object.getOwnPropertySymbols(proxy)
  • Object.keys(proxy)
  • for...in loop

The above interceptions all return an array.

This method returns the property names of all its own properties of the target object, while Object.keys() only includes the traversable properties of the target object itself.

getOwnPropertyDescriptor(target, propKey)

Intercept Object.getOwnPropertyDescriptor(proxy, propKey) and return the description object of the property.

defineProperty(target, propKey, propDesc)

Intercept:

  • Object.defineProperty(proxy, propKey, propDesc)
  • Object.defineProperties(proxy, propDescs)

Returns a boolean value.

preventExtensions(target)

Intercept Object.preventExtensions(proxy) , return a boolean.

getPrototypeOf(target)

Intercept Object.getPrototypeOf(proxy) and return an object.

isExtensible(target)

Intercept Object.isExtensible(proxy) , return a boolean.

setPrototypeOf(target, proto)

Intercept Object.setPrototypeOf(proxy, proto) , return a boolean.

If the target object is a function, there are two additional operations that can be intercepted.

apply(target, object, args)

Intercept the operation of the Proxy instance as a function call, such as:

  • proxy(...args)
  • proxy.call(object, ...args)
  • proxy.apply(...)

construct(target, args)

Intercept the operation of the Proxy instance as a constructor call, for example: new proxy(...args) .

~

~ This article is over, thanks for reading!

~

Learn interesting knowledge, meet interesting friends, and shape interesting souls!

Hello everyone, I is [ programming Samadhi of〗 of hermit king , my public number is " programming Samadhi " welcome attention, we hope the exhibitions!


编程三昧
54 声望10 粉丝

学习有趣的知识,交识有趣的朋友,造就有趣的灵魂!