代理与反射(二)

230 阅读2分钟

咱们接着上一节内容,继续学习come baby^~^

2.代理捕获器与反射方法

   只要在代理上调用,所有捕获器都会拦截他们对应的反射API操作。

  a. get()

 捕获器会在获取属性值的操作中被调用,对应的API方法为Reflect.get();

const myTarget={};
const proxy = new Proxy(myTarget,{
    get(target,property,receiver){
        console.log('get()')
        return Reflect.get(...arguments)
    }
});
proxy.foo;
//get();

1.返回值

 返回值无限制

2.拦截的操作

proxy.property

proxy[property]

Object.create(proxy)[property]

Reflect.get(proxy,property,receiver)

3.捕获器处理程序参数

target:目标对象

property;引用的目标对象上的字符串键属性

receiver:代理对象或者继承代理对象的对象

4.捕获器不变式

如果target.property不可写且不可配置,则处理程序返回的值必须与target.property匹配。

如果target.property不可写且[[Get]]特性为undefined,则处理程序返回的值必须是undefined。

b.set()

捕获器会在获取属性值的操作中被调用,对应的API方法为Reflect.set();

const myTarget={};
const proxy = new Proxy(myTarget,{
    set(target,property,value,receiver){
        console.log('set()')
        return Reflect.get(...arguments)
    }
});
proxy.foo;
//set();

1.返回值

返回值为true表示成功,false为失败严格模式下抛出TypeError.

2.拦截的操作

proxy.property = value

proxy[property] = value

Object.create(proxy)[property] = value

Reflect.set(proxy,property,value,receiver)

3.捕获器处理程序参数

target:目标对象

property:引用的目标对象上的字符串键属性

value:要赋给属性的值

receiver:接收最初赋值的对象

4.捕获器不变式

如果target.property不可写且不可配置,则不能修改目标属性的值;

如果target.property不可写且[[Set]]特性为undefined,则不能修改目标属性的值;

严格模式下返回false会抛出TypeError.

c.defineProperty()

defineProperty捕获器会在Object.defineProperty()中被调用,对应的反射API方法为Reflect.defineProperty();

const myTarget={};
const proxy = new Proxy(myTarget,{
    defineProperty(target,property,descriptor){
        console.log('defineProperty()')
        return Reflect.defineProperty(...arguments)
    }
});
Object.defineProperty(proxy,'foo',{value:'kkb'});
//defineProperty();

1.返回值

返回值为布尔值,表示属性是否成功定义,返回非布尔值会被转型为布尔值。

2.拦截的操作

 Object.defineProperty(target,property,descriptor)
Reflect.defineProperty(target,property,descriptor)

3.捕获器处理程序参数

target:目标对象

property:引用的目标对象上的字符串键属性

descriptor:包含可选的enumerble、configurable、writable、value、get、set定义的对象

4.捕获器不变式

如果目标对象不可扩展,则无法定义属性;

如果目标对象有一个可配置的属性,则不能添加同名的不可配置的属性。

如果目标对象有一个不可配置的属性,则不能添加同名的可配置的属性。

d.数据绑定与可观察对象

通过代理可以把不相关的部分联系在一起,从而实现各种模式,不同的代码相互操作

比如:可以将被代理的类绑定到一个全局实例的集合,让所有创建的实例都被添加到这个集合中

const nameList=[];
class  Name {
    constructor(name){
        this.name_ = name;
    }
}
const proxy = new Proxy(Name,{
    constructor(){
        const newName = Reflect.constructor(...arguments)
        nameList.push(newName);
        return newName;
    }
})
new proxy('Amy');
new proxy('BOb');
new proxy('KIKI');
console.log(nameList);  // []