js代理(Proxy)和反射(Reflection)

更新时间:2023-07-25 11:32:27 阅读: 评论:0

js代理(Proxy)和反射(Reflection)
在实际开发中经常会遇到js抛出的错误,但是我们有没有想过⾃⼰去接管js异常验证,根据⾃⼰的需求抛出异常呢?原本也许不⾏,但是在es6出来后就可以做到了
⼀、代理(Proxy)
什么是‘代理’ 呢?代理:就是调⽤new 创建⼀个和⽬标(traget)对象⼀直的虚拟化对象,然该代理中就可以拦截JavaScript引擎内部⽬标的底层对象的操作;这些底层操作被拦截后会触发响应特定操作的陷阱函数
来看个简单的案例
let tartget = {};
let proxy = new Proxy(target,{});
proxy.name = 'proxy';
console.log(proxy.name); // proxy
console.log(tartget .name); // proxy
tartget .name = 'tartget';
console.log(proxy.name); // target
console.log(tartget .name); // target
如案例
如proxy.name = 'proxy';将proxy赋值给proxy.name时,代理就会将该操作转发给⽬标,执⾏name属性的创建;然⽽他只是做转发⽽不会存储该属性;
so他们之间存在⼀个相互引⽤;tartget .name设置⼀个新值后,proxy.name值也改变了;
⼆、反射(Reflect)
那反射⼜是什么呢?反射:它提供了⼀个Reflect对象API;该对像中的⽅法默认特性与底层的操作对应;⽽每⼀个代理陷阱会对应⼀个命名和参数都相同的Reflect⽅法(其实就是每个代理陷阱都会对应⼀个Reflect api接⼝供覆写JavaScript底层操作)
映射关系如下表:
代理陷阱覆写的特性默认特性
get读写⼀个属性值()
t写⼊⼀个属性Reflect.t()
has in操作Reflect.has()
deleteProperty delete操作符Reflect.deleteProperty() APrototypeof ()APrototypeof () tAPrototypeof Object.tAPrototypeof ()Reflect.tAPrototypeof () isExtensible Object.isExtensible()Reflect.isExtensible() preventExtensions Object.preventExtensions()Reflect.preventExtensions() OwnPropertyDescriptor()OwnPropertyDescriptor() defineaProperty Object.defineaProperty()Reflect.defineaProperty()
ownKeys Object.keys() 、 OwnPropertyNames()和
殿堂楼阁
Reflect.ownKeys()
apply调⽤⼀个函数Reflect.apply() construct⽤new调⽤⼀个函数struct()
三、使⽤t陷阱验证属性
接下来使⽤t陷阱来验证⼀下对象属性赋值操作(如为对象新增属性,要求必须赋值为int)
let target = {
name :'target'
};
let proxy = new Proxy(target,{
t(trapTarget,key,value,receiver){
//忽略不希望受到影响的已有属性
if(!trapTarget.hasOwnProperty(key)){
if(isNaN(value)){
throw new TypeError("属性必须是数字哟,亲!");
}
}
// 添加属性
return Reflect.t(trapTarget,key,value,receiver);
}
});
// 添加⼀个新属性
console.unt); // 1
console.unt); // 1
// 由于⽬标已有name属性,so 如上第⼀个if不成⽴(赋值成功)
proxy.name= "proxy";
console.log(proxy.name); // proxy
console.log(proxy.name); // proxy
// 新建⼀个属性同时赋值⼀个⾮int 值,第⼀个if成⽴,第⼆个if验证isNaN(key) = true 即抛出异常
proxy.anotherName = "proxy";
案例中t(trapTarget,key,value,receiver)这个t陷阱默认接收四个参数
trapTarget ⽤于接收属性(代理的⽬标)的对象
key 要写⼊的属性键(字符串或Symbol类型)
value 被写⼊的属性的值
receiver 操作发⽣的对象(通常是代理)
s6三星四、使⽤get 陷阱验证对象结构
let target = {};
console.log(target.name); // undefined
在JavaScript中调⽤⼀个对象不存在的属性不会报错,反⽽使⽤undefined代替被读取属性的值
⽽喝多时候会带来意想不到的bug,现在我们可以使⽤get陷阱来验证该问题
依然看这个案例
let proxy = new Proxy(target,{梦到熊
get(trapTarget,key,receiver){
//忽略不希望受到影响的已有属性
if(!(key in receiver)){
throw new TypeError("sorry 亲!你找的 "+key+" 属性不存在。!")安徽特产有哪些土特产
}
// 添加属性
(trapTarget,key,receiver);
}
});
// 添加⼀个属性,
proxy.name= "proxy";
console.log(proxy.name); // proxy
// 读取⼀个不存在的属性直接会抛出异常
console.);
如上使⽤in操作判断receiver中是否存在被读取的属性;如果没有抛出异常
其中get(trapTarget,key,receiver)参数
trapTarget 被读取属性源对象(代理的⽬标)
key 要读取的属性键(字符串或Symbol类型)
receiver 操作发⽣的对象(通常是代理)
五、函数代理apply和construct陷阱
使⽤这个两个陷阱来验证函数调⽤时的参数的正确性
如下案例
// 参数求和
function sum (...values){
duce((previous,current) => prvious + current, 0);
}
let sumProxy = new Proxy(sum,{
apply:function(trapTarget,thisArg,argumentList){
argumentList.forEach(arg => {
老式高压锅怎么用
if(typeof arg !== "number"){
throw new TypeError("所有参数必须是数字,亲!");
}
});
return Reflect.apply(trapTarget,thisArg,argumentList);
},
/
/ 防⽌使⽤new 关键字调⽤
construct:function(trapTarget,argumentList){
throw new TypeError("亲,你不能这么⼲,该函数不能通过new调⽤。");
}
});
// 测试哈
console.log(sumProxy(1,2,3,4)); // 10
分割构成>保安服务合同// 传⼊⼀个⾮数字的属性值试试【直接抛出异常】
console.log(sumProxy(1,“2”,3,4)); // 10
// 同样使⽤new调⽤【直接抛出异常】
let result = new sumProxy();
apply陷阱和Reflect.apply()都接受同样的参数
trapTarget 被执⾏的函数(代理的⽬标)
thisArg 函数被调⽤时内部的this的值
argumentList传递给函数的参数数组
老舍散文
当使⽤new调⽤函数时会触发construct陷阱,接收的参数为
trapTarget 被执⾏的函数(代理的⽬标)
argumentList传递给函数的参数数组
其中struct()第三个参数是newTarget 这是⼀个可选参数。⽤于指定该函数内部new.target的值
看到这⾥有没有感觉这个对于js项⽬代码检测还是蛮有⽤处的呢。
ok先到这⾥,时间不早了改且休息了;改天继续…

本文发布于:2023-07-25 11:32:27,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1095990.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:属性   陷阱   对象   操作   参数
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图