javascript高级程序设计阅读收获(9.2)——代理捕获器与反射方法

内容简介

  1. 代理可以捕获13种不同的基本操作。这些操作有各自不同的反射API方法、参数、关联ECMAScript操作和不变式。
  2. 有几种不同的JavaScript操作会调用同一个捕获器处理程序。对于在代理对象上执行的任何一种操作,只会有一个捕获处理程序被调用,不会存在重复捕获的情况。
  3. 只要在代理上调用,所有的捕获器都会拦截它们对应的反射API操作。

1.get()

const myTarget = {};

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

proxy.foo;//get()
  1. get捕获器在获取属性值的操作中被调用,对应的反射API方法是Reflect.get()。
  2. get捕获器的返回值无限制。
  3. get捕获器能够拦截的操作:
    (1)proxy.property
    (2)proxy[property]
    (3)Object.create(proxy)[property]
    (4)Reflect.get(proxy,property,receiver)
  4. get捕获器处理程序参数
    (1)target:目标对象。
    (2)property:引用的目标对象上的字符串键属性。
    (3)receiver:代理对象或继承代理对象的对象。
  5. get捕获器IDE捕获不定式
    (1)如果target.property不可写不可配置,则处理程序返回的值必须与target.property匹配。
    (2)如果target.property不可配置且[[get]]特性为undefined,处理程序的返回值也必须是undefined。

2.set()

const myTarget = {};
const proxy = new Proxy(myTarget,{
	set(target, property, value, receiver){
		console.log('set()');
		return Reflect.set(...arguments);
	}
});
proxy.foo = 'bar';//"set()"
  1. set捕获器在设置属性值的操作中被调用,对应的反射API为Reflect.set()。
  2. set捕获器的返回值:
    (1)true:表示成功;
    (2)false:表示失败,严格模式下会抛出TypeError。
  3. set捕获器可以拦截的操作:
    (1)proxy.property = value
    (2)proxy[property] = value
    (3)proxy.create(proxy)[property] = value
    (4)proxy.set(proxy,property,value,receiver)
  4. set捕获器处理程序参数
    (1)target:目标对象。
    (2)property:引用的目标对象上的字符串键属性。
    (3)value:要赋给属性的值。
    (4)receiver:接收最初赋值的对象。
  5. set捕获器不变式
    (1)如果target.property不可写不可配置,则不能修改目标属性的值。
    (2)如果target.property不可配置且[[set]]特性为undefined,则不能修改目标属性的值。
    (3)在严格模式下,处理程序中返回false会抛出TypeError。

3.has()

const myTarget = {};

const proxy = new Proxy(myTarget,{
	has(target,property){
		console.log('has()');
		return Reflect.has(...arguments)
	}
});
'foo' in proxy;//has()
//false
  1. has捕获器会在in操作符中被调用,对应的反射API方法为Reflect.has()。
  2. has捕获器必须返回布尔值,表示属性是否存在。返回非布尔值会被转型为布尔值
  3. has捕获器拦截的操作:
    (1)property in proxy
    (2)property in Object.create(proxy)
    (3)with(proxy){(property);}
    (4)Reflect.has(proxy,property)
  4. 捕获器处理程序参数
    (1)target:目标对象
    (2)property:引用的目标对象上的字符串属性
  5. 捕获器不变式
    (1)如果target.property存在且不可配置,则处理程序必须返回true。
    (2)如果target.property存在且目标对象不可扩展,则处理程序必须返回true。

4.defineProperty()

const myTarget = {};

const proxy = new Proxy(myTarget,{
	defineProperty(target,property,descriptor){
		console.log('defineProperty()');
		return Reflect.defineProperty(...arguments);
	}
})

Object.defineProperty(proxy,'foo',{value:'bar'});//Proxy {foo: "bar"}
  1. defineProperty捕获器会在Object.defineProperty()中被调用,对应的反射API方法为Reflect.defineProperty()。
  2. defineProperty捕获器必须先返回布尔值,表示属性是否成功定义。返回非布尔值会被转型为布尔值。
  3. defineProperty捕获器拦截的操作:
    (1)Object.defineProperty(proxy,property,descriptor)
    (2)Reflect.defineProperty(proxy,property,descriptor)
  4. defineProperty捕获器处理程序参数:
    (1)target:目标对象
    (2)property:引用的目标对象上的字符串键属性。
    (3)descriptor:包含可选的enumberable、configurable、writable、value、get和set定义的对象。
  5. defineProperty捕获器不变式:
    (1)如果目标对象不可扩展,则无法定义属性。
    (2)如果目标对象有一个可配置的属性,则不能添加同名的不可配置属性。
    (3)如果目标对象有一个不可配置的属性,则不能添加同名的可配置属性。

5.getOwnPropertyDescriptor()

const myTarget = {};

const proxy = new Proxy(myTarget,{
	getOwnPropertyDescriptor(target,property){
		console.log('getOwnPropertyDescriptor()');
		return Reflect.getOwnPropertyDescriptor(...arguments);
	}
})
  1. getOwnPropertyDescriptor捕获器会在Object.getOwnPropertyDescriptor()中被调用,对应的反射API方法为Reflect.getOwnPropertyDescriptor().
  2. getOwnPropertyDescriptor捕获器必须返回对象,或者在属性不存在时返回undefined。
  3. getOwnPropertyDescriptor捕获器拦截的操作:
    (1)Object.getOwnPropertyDescriptor(proxy,property)
    (2)Reflect.getOwnPropertyDescriptor(proxy,property)
  4. getOwnPropertyDescriptor捕获器处理程序参数:
    (1)target:目标对象。
    (2)property:引用的目标对象上的字符串键属性。
  5. getOwnPropertyDescriptor捕获器不变式
    (1)如果自有的target.property存在且不可配置,则处理程序必须返回一个表示该属性存在的对象。
    (2)如果自有的target.property存在且可配置,则处理程序必须返回表示该属性可配置的对象。
    (3)如果自有的target.property存在且target不可扩展,则处理程序必须返回一个表示该属性存在的对象。
    (4)如果target.property不存在且target不可扩展,则处理程序必须返回undefined表示该属性不存在。
    (5)如果target.property不存在,则处理程序不能返回表示该属性可配置的对象。

6.deleteProperty()

const myTarget = {};

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

delete proxy.foo;//deleteProperty()
  1. deleteProperty捕获器会在delete操作符中被调用,对应的反射API方法会Reflect.deleteProperty()。
  2. deleteProperty捕获器必须返回布尔值,表示删除属性是否成功,返回非布尔值会被转型为布尔值。
  3. deleteProperty捕获器拦截的操作:
    (1)delete proxy.property
    (2)delete proxy[property]
    (3)Reflect.deleteProperty(proxy,property)
  4. deleteProperty捕获器处理程序参数:
    (1)target:目标对象。
    (2)property:引用的目标对象上的字符串键属性。
  5. deleteProperty捕获器不变式:如果自有的target.property存在且不可配置,则处理程序不能删除这个属性。

7.ownKeys()

const myTarget = {};

const proxy = new Proxy(myTarget,{
	ownKeys(target){
		cosnole.log('ownKeys()');
		return Reflect.ownKeys(...arguments)
	}
})

Object.keys(proxy);//ownKeys()
  1. ownKeys捕获器会在Object.keys()及类似方法中被调用。对应的反射API方法为Reflect.ownKeys()。
  2. ownKeys捕获器必须返回包含字符串或符号的可枚举对象。
  3. ownKeys捕获器拦截的操作:
    (1)Object.getOwnPropertyNames(proxy)
    (2)Object.getOwnPeopertySymbols(proxy)
    (3)Object.keys(proxy)
    (4)Reflect.wonKeys(proxy)
  4. ownKeys捕获器处理程序参数:
    (1)target:目标对象。
  5. ownKeys捕获器不变式:
    (1)返回的可枚举对象必须包含target的所有不可配置的自有属性。
    (2)如果target不可扩展,则返回可枚举对象必须准确地包含自有属性键。

8.getPrototypeOf()

const mytarget = {};
const proxy = new Proxy(myTarget,{
	getPrototypeOf(target){
		console.log('getProptyoeOf()');
		return Reflect.getPrototypeOf(...arguments);
	}
});

Object.getPrototypeOf(proxy);//getPrototypeOf()
  1. getPrototypeOf捕获器会在Object.getPrototypeOf()中被调用,对应的反射API方法为Reflect.getPrototypeOf()。
  2. getPrototypeOf必须返回对象或null。
  3. getPrototypeOf拦截的操作:
    (1)Object.getPrototypeOf(proxy)
    (2)Reflect.getPrototypeOf(proxy)
    (3)proxy.__proto__
    (4)Object.prototype.isPrototypeOf(proxy)
    (5)proxy instanceof Object
  4. getPrototypeOf捕获器处理程序参数
    (1)target:目标对象。
  5. getPRototypeOf捕获器不变式:如果target不可扩展,则Object.getPrototypeOf(proxy)唯一有效的返回值就是Object.getPrototypeOf(target)的返回值

9.setPrototypeOf()

const myTarget = {}

const proxy = new Proxy(myTarget,{
	setPrototypeOf(target,prototype){
		console.log('setPrototypeOf()');
		return Reflect.setPrototypeOf(...arguments)
	}
});

Object.setPrototypeOf(proxy,Object);//setPrototypeOf()
  1. setPrototypeOf捕获器会在Object.setPrototypeOf()中被调用。对应的反射API方法为Reflect.getPrototypeOf()。
  2. setPrototypeOf捕获器必须返回布尔值,表示原型赋值是否成功。返回非布尔值会被转型为布尔值。
  3. setPrototypeOf捕获器拦截的操作:
    (1)Object.setPrototypeOf(proxy)
    (2)Reflect.setPrototypeOf(proxy)
  4. setPrototypeOf捕获器处理程序参数
    (1)target:目标对象。
    (2)prototype:target的替代原型,如果是顶级原型则为null。
  5. setPrototypeOf捕获器不变式:如果target不可扩展,则唯一有效的prototype参数就是Object.getPrototypeOf(target)的返回值。

10.isExtensible()

const myTarget = {};
const proxy = new Proxy(myTarget,{
	isExtensible(target){
		console.log('isExtensible()');
		return Reflect.isExtensible(...arguments)
	}
});
Object.isExtensible(proxy);//isExtensible()
  1. isExtensible捕获器会在Object.isExtensible()中被调用,对应的反射API方法为Reflect.isExtenSible()。
  2. isExtensible捕获器必须返回布尔值,表示target是否可扩展。返回非布尔值会被转型为布尔值。
  3. isExtensible捕获器拦截的操作:
    (1)Object.isExtensible(proxy)
    (2)Reflect.isExtensible(proxy)
  4. isExtensible捕获器处理程序参数:
    (1)target:目标对象
  5. isExtensible捕获不变式:
    (1)如果target可扩展,则处理程序必须返回true。
    (2)如果target不可扩展,则处理程序必须返回false。

11.preventExtensions()

const myTarget = {};

const proxy = new Proxy(myTarget,{
	preventExtensions(target){
		console.log('preventExtensions()');
		return Reflect.preventExtensions(...arguments)
	}
});

Object.preventExtensions(proxy);//preventExtensions()
  1. preventExtensions捕获器会在Object.preventExtensions()中被调用。对应的反射API方法为Reflect.preventExtensions()。
  2. preventExtensions捕获器必须返回布尔值,表示target是否已经不可扩展。返回非布尔值会被转型为布尔值。
  3. preventExtensions捕获器拦截的操作:
    (1)Object.preventExtensions(proxy)
    (2)Reflect.preventExtensions(proxy)
  4. preventExtensions捕获器处理程序参数:
    (1)target:目标对象
  5. preventExtensions捕获器不变式:如果Object.isExtensible(proxy)是false,则处理程序必须返回true

12.apply()

const myTarget = () => {};
const proxy = new Proxy(myTarget,{
	apply(target,thisArg,...argumentsList){
		console.log('apply()');
		return Reflect.apply(...arguments)
	}
})
proxy();//apply()
  1. apply捕获器会在调用函数时中被调用。对应的反射API方法为Reflect.apply()。
  2. apply捕获器返回值无限制。
  3. apply捕获器拦截的操作:
    (1)proxy(…arguments)
    (2)Function.prototype.apply(thisArg,argumentsList)
    (3)Function/prototype.call(thisArg,…argumentsList)
    (4)Reflect.apply(target,thisArgument,argumentList)
  4. apply捕获器处理程序参数:
    (1)target:目标对象
    (2)thisArg:调用函数时的this参数
    (3)argumentsList:调用函数时的参数列表
  5. apply捕获器不变式:target必须是一个函数对象

13.construct()

const myTarget = function(){};
const proxy = new Proxy(myTarget,{
	construct(target,argumentsList,newTarget){
		console.log('construct()');
		return Reflect.construct(...arguments)
	}
});
new proxy;
  1. construct捕获器会在new操作符中被调用。对应的反射API方法为Reflect.construct()。
  2. construct捕获器必须返回一个对象。
  3. construct捕获器拦截的操作:
    (1)new proxy(…argument)
    (2)Reflect.construct(target, argumentsList, newTarget)
  4. construct捕获器处理程序参数
    (1)target:目标构造函数
    (2)argumentsList:传给目标构造函数的参数列表
    (3)newTarget:最初被调用的构造函数
  5. construct捕获器不变式:target必须可以用作构造函数
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木子 旭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值