proxy

Proxy 是什么?

Proxy 是由 ES6 原生提供的一个构造函数

Proxy 指在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。

作用

Proxy 的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。

Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程。

使用方法

参数

Proxy 作为一个构造函数,它接受两个参数。

const p = new Proxy(target, handler)

第一个参数是所要代理的目标对象即target

target要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。

第二个参数是一个配置对象,对于每一个被代理的操作,需要提供一个对应的处理函数即handler,该函数将拦截对应的操作。

handler一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 p 的行为。

Proxy.revocable()

创建一个可撤销的Proxy对象。

配置对象的方法

有一个 get 方法,用来拦截对目标对象属性的访问请求,而 get 方法两个参数分别是目标对象(target)和所要访问的属性(prop)。

注意:要使得 Proxy 起作用,必须针对 Proxy 实例进行操作,而不是针对目标对象进行操作。

//new Proxy()表示生成一个Proxy实例
var proxy = new Proxy({}, {
    get: function(target, propKey) {
        return 35;
    }
});
console.log(proxy.name) // 35
console.log(proxy.sex) // 35
console.log(proxy.age) // 35
//可以看到,由于拦截函数总是返回35,所以访问任何属性都得到35。

//如果handler没有设置任何拦截,那就等同于直接通向原对象。
var target = {};
var handler = {};
var proxy2 = new Proxy(target, handler);
proxy2.a = 'b';
target.a // "b"

//Proxy 实例也可以作为其他对象的原型对象。
var proxy3 = new Proxy({},{
    return 35
})
let obj = Obeject.create(proxy3)
console.log(obj.name) // 35
//上述代码proxy3对象是obj对象的原型,obj对象本身并没有name属性,所以根据原型链,会在proxy3对象上读取该属性,导致被拦截。

//同一个拦截器函数,可以设置拦截多个操作。
var handler = {
    get: function(target, name) {
        if (name === 'prototype') {
            return Object.prototype;
        }
        return 'Hello, ' + name;
    },
    apply: function(target, thisBinding, args) {
        return args[0];
    },
    construct: function(target, args) {
        return {value: args[1]};
    }
};
var fproxy = new Proxy(function(x, y) {
    return x + y;
}, handler);
fproxy(1, 2) // 1
new fproxy(1, 2) // {value: 2}
fproxy.prototype === Object.prototype // true
fproxy.foo === "Hello, foo" // true

Proxy 实例的方法

get()

get 方法用于拦截某个属性的读取操作。

可接受三个参数:

  1. 目标对象(target
  2. 属性名(prop
  3. proxy 实例本身(receiver)(严格地说,是操作行为所针对的对象),其中最后一个参数可选。

set()

set用来拦截某个属性的赋值操作。

可接受四个参数:

  1. 目标对象(target
  2. 属性名(prop
  3. 属性值(value
  4. Proxy 实例本身(receiver),其中最后一个参数可选。

apply()

apply 方法拦截函数的调用、callapply 操作。

apply 方法可接受三个参数

  1. 目标对象 (target
  2. 目标对象的上下文对象(ctx
  3. 目标对象的参数数组(…arguments

has()

has()方法用来拦截 HasProperty 操作,即判断对象是否具有某个属性时,这个方法会生效。
典型的操作就是 in 运算符。

has()方法可接受两个参数:

  1. 目标对象
  2. 需查询的属性名。

construct()

用于拦截 new 命令,拦截对象的写法:

const handler = {
  construct (target, args, newTarget) {
    return new target(...args);
  }
};

construct() 可接受三个参数:

  1. target:目标对象。
  2. args:构造函数的参数数组。
  3. newTarget:创造实例对象时,new 命令作用的构造函数。
const p = new Proxy(function () {}, {
  construct: function(target, args) {
    console.log('called: ' + args.join(', '));
    return { value: args[0] * 10 };
  }
});

(new p(1)).value
// "called: 1"
// 10

注意

由于 construct()拦截的是构造函数,所以它的目标对象必须是函数,否则就会报错。

construct()方法中的 this 指向的是 handler,而不是实例对象。

headler对象的方法

handler 对象是一个容纳一批特定属性的占位符对象。它包含有 Proxy 的各个捕获器(trap)。

所有的捕捉器是可选的。如果没有定义某个捕捉器,那么就会保留源对象的默认行为。

handler.getPrototypeOf()
Object.getPrototypeOf 方法的捕捉器。

handler.setPrototypeOf()
Object.setPrototypeOf 方法的捕捉器。

handler.isExtensible()
Object.isExtensible 方法的捕捉器。

handler.preventExtensions()
Object.preventExtensions 方法的捕捉器。

handler.getOwnPropertyDescriptor()
Object.getOwnPropertyDescriptor 方法的捕捉器。

handler.defineProperty()
Object.defineProperty 方法的捕捉器。

handler.has()
in 操作符的捕捉器。

handler.get()
属性读取操作的捕捉器。

handler.set()
属性设置操作的捕捉器。

handler.deleteProperty()
delete 操作符的捕捉器。

handler.ownKeys()
Object.getOwnPropertyNames 方法和 Object.getOwnPropertySymbols 方法的捕捉器。

handler.apply()
函数调用操作的捕捉器。

handler.construct()
new 操作符的捕捉器。

点我 VUE 3官网

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值