反射和代理

什么是反射和代理?

反射 :ES6 的反射 API 以 Reflect 对象的形式出现,对象每个方法都与对应的陷阱函数同名,并且接收的参数也与之一致。
代理 :代理是用来替代另一个对象(target),JS 通过new Proxy()创建一个目标对象的代理,该代理与该目标对象表面上可以被当作同一个对象来对待。

代理陷阱覆写的特性默认特性
get读写一个属性值Reflect.get()
set写入一个属性Reflect.set()
hasin操作Reflect.has()
deletePropertydelete操作符Reflect.deleteProperty()
getAPrototypeofObject.getAPrototypeof ()Reflect.getAPrototypeof ()
setAPrototypeofObject.setAPrototypeof ()Reflect.setAPrototypeof ()
isExtensibleObject.isExtensible()Reflect.isExtensible()
preventExtensionsObject.preventExtensions()Reflect.preventExtensions()
getOwnPropertyDescriptorObject.getOwnPropertyDescriptor()Reflect.getOwnPropertyDescriptor()
defineaPropertyObject.defineaProperty()Reflect.defineaProperty()
ownKeys Object.keys()Object.getOwnPropertyNames()和 Object.getOwnPropertySysmbols()Reflect.ownKeys()
apply调用一个函数Reflect.apply()
construct用new调用一个函数Reflect.construct()
代理

当你使用 Proxy 构造器来创建一个代理时,需要传递两个参数:目标对象(target)以及一个处理器( handler),下面我们创建一个简单的代理。

// 目标对象
let target = {}; 
// 代理对象
let proxy = new Proxy(target, {});

proxy.name = "hello";
console.log(proxy.name); // "hello"
console.log(target.name); // "hello"

target.name = "world";
console.log(proxy.name); // "world"
console.log(target.name); // "world

proxy.name = ‘hello’; 将hello赋值给proxy.name时,代理就会将该操作转发给目标,执行name属性的创建;然而他只是做转发而不会存储该属性;所以他们之间存在一个相互引用;tartget .name设置一个新值后,proxy.name值也改变了;

set 验证对象属性的存储
如果想要创建一个对象,并要求其属性值只能是数值,这就意味着该对象的每个新增属性
都要被验证,并且在属性值不为数值类型时应当抛出错误。
这时需要使用 set 陷阱函数来拦截传入的 value,该陷阱函数能接受四个参数:
trapTarget :将接收属性的对象( 即代理的目标对象)
key :需要写入的属性的键( 字符串类型或符号类型)
value :将被写入属性的值;
receiver :操作发生的对象( 通常是代理对象)
set 陷阱对应的反射方法和默认特性是Reflect.set(),和陷阱函数一样接受这四个参数,并会基于操作是否成功而返回相应的结果

llet targetObj = {};
let proxyObj = new Proxy(targetObj, {
 set: set
});
/* 定义 set 陷阱函数 */
function set (trapTarget, key, value, receiver) {
 if (isNaN(value)) {
   throw new TypeError("Property " + key + " must be a number.");
 }
 return Reflect.set(trapTarget, key, value, receiver);
}
 
proxyObj.count = 1;
console.log(proxyObj.count); // 1
console.log(targetObj.count); // 1
proxyObj.anotherName = "proxy" // TypeError

get 验证对象属性的读取
get 陷阱函数会在读取属性时被调用,即使该属性在对象中并不存在,它能接受三个参数:
trapTarget :将会被读取属性的对象( 即代理的目标对象)
key :需要读取的属性的键( 字符串类型或符号类型)
receiver :操作发生的对象( 通常是代理对象)
Reflect.get()方法接受与之相同的参数,并返回默认属性的默认值。

let proxyObj = new Proxy(targetObj, {
 set: set,
 get: get
});
 
/* 定义 get 陷阱函数 */
function get(trapTarget, key, receiver) {
 if (!(key in receiver)) {
  throw new TypeError("Property " + key + " doesn't exist.");
 }
 return Reflect.get(trapTarget, key, receiver);
}

console.log(proxyObj.count); // 1
console.log(proxyObj.newcount) // TypeError
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值