ES6 Proxy代理

Posted liangtao999

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ES6 Proxy代理相关的知识,希望对你有一定的参考价值。

概述

Proxy代理 可以对目标对象的读取、函数调用等操作进行拦截,然后进行操作处理。它不直接操作对象,而是像代理模式。

基本用法

Proxy代理

一个 Proxy 对象由两个部分组成: target 、 handler 。在通过 Proxy 构造函数生成实例对象时,需要提供这两个参数。 target 即目标对象, handler 是一个对象,声明了代理 target 的指定行为。

let target = {   // target 可以为空对象,调用 set 方法,向目标对象中添加了 属性
    name: ‘Tom‘,
    age: 24
}
let handler = {
    get: function(target, key) {
        console.log(‘getting ‘+key);
        return target[key]; // 不是target.key
    },
    set: function(target, key, value) {
        console.log(‘setting ‘+key);
        target[key] = value;
     return true; //严格模式下,set代理如果没有返回true,就会报错。 } } let proxy
= new Proxy(target, handler) proxy.name // 实际执行 handler.get proxy.age = 25 // 实际执行 handler.set

实例方法

1、get(target, propKey, receiver) 用于拦截某个属性的读取(read)操作,就是在读取目标对象的属性之前,搞点事情。
参数:
target:目标对象
property:属性名
receiver:操作行为所针对的对象,一般指proxy实例本身
let exam={};
let proxy = new Proxy(exam, { get(target, propKey, receiver) { console.log(‘Getting ‘ + propKey); return target[propKey]; } })
console.log(proxy.name);//undefined
2、set(target, propKey, value, receiver) 用来拦截目标对象的赋值(write)操作
参数:
target:目标对象
propertyName:属性名
propertyValue:属性值
receiver:Proxy实例本身
let validator = {
    set: function(obj, prop, value) {
        if (prop === ‘age‘) {
            if (!Number.isInteger(value)) {
                throw new TypeError(‘The age is not an integer‘);
                return false;    
            }
            if (value > 200) {
                throw new RangeError(‘The age seems invalid‘);
                return false;
            }
        }
        // 对于满足条件的 age 属性以及其他属性,直接保存
        obj[prop] = value;
        return true;
    }
};
let proxy= new Proxy({}, validator)
proxy.age = 100;
proxy.age           // 100
proxy.age = ‘oppps‘ // 报错
proxy.age = 300     // 报错   

3、apply(target, ctx, args)  用于拦截函数的调用、call 和 reply 操作。

  target 表示目标对象,

  ctx 表示目标对象上下文,

  args 表示目标对象的参数数组。

function sub(a, b){
    return a - b;
}
let handler = {
    apply: function(target, ctx, args){
        console.log(‘handle apply‘);
        return Reflect.apply(...arguments);
    }
}
let proxy = new Proxy(sub, handler)
proxy(2, 1) 
// 1

4、has(target,propkey)   拦截 propKey in proxy 的操作,返回一个布尔值。即在判断 target 对象是否存在 propKey 属性时,会被这个方法拦截。

let proxy = new Proxy(exam, handler)
‘name‘ in proxy  

5、deleteProperty(target, propKey) 拦截delete proxy[propKey]的操作,返回一个布尔值。用于拦截 delete 操作。

6、construct(target, args) 用于拦截 new 命令。返回值必须为对象。

7、ownKeys(target) 用于拦截对象自身属性的读取操作。

8、getPrototypeOf(target) 拦截对象原型操作

9、isExtensible(target) 用于拦截 Object.isExtensible 操作。

扩展:

javascript中,对象的extensible属性用于表示是否允许在对象中动态添加新的property。ECMAScript 3标准中,所有的对象都是extensible的。ECMAScript 5标准中,所有的对象默认仍是extensible的,但可以通过设定来改变这一属性。查询一个对象是否是extensible的,可以使用Object.isExtensible()语句:

……

 

学习原文

 

以上是关于ES6 Proxy代理的主要内容,如果未能解决你的问题,请参考以下文章

ES6-Proxy,代理

关于es6代理对象proxy

ES6深入浅出-13 Proxy 与 Reflect-2.Proxy 代理

ES6 Proxy和Reflect

ES6中的代理模式-----Proxy

Es6新特性Proxy代理用法解析