js高阶-监听对象的操作
控制与监听对象的行为
需求:监听对象中的属性设置与访问的过程
Object.defineProperty()
缺点
设计初衷是设置属性描述符,监听更加丰富的操作比如新增属性,删除操作是无能为力的
// 1.监听对象的某个属性的操作
Object.defineProperty(obj,'name',{
set:function(val){
console.log("设置值",val);
this._name=val //使用一个属性来存值
},
get:function(){
console.log("获取值");
return this._name
}
})
//2.监听某个对象的所有属性操作
Object.keys(obj).forEach((key)=>{
let val = obj[key] // 暂存原值
Object.defineProperty(obj,key,{
get(){
console.log(`get key ${key}`);
return val
},
set(newVal){
console.log(`set key ${key}:`,newVal);
val=newVal
}
}
)
})
Proxy
es6新增类,用来创建代理对象,通过给对象创建代理对象,之后所有对对象进行的操作都可以通过代理对象进行
new Proxy(target,handler)
handler
handler处理器对象,中的属性称为捕获器,拦截对代理对象的一些操作,一共13个
实现原理
内部维护一个对象,关联了target与handler,当对代理对象进行操作的时候,会先送到handler
常用的捕获器
| 方法 | 对应操作 | 描述 |
| ---- | -------- | ------------------ |
| get | 属性读取 | 拦截属性读取操作 |
| set | 属性设置 | 拦截属性设置操作 |
| has | in操作 | 拦截属性存在性检查 |
| deleteProperty |delete操作 | 拦截删除属性操作 |
let proxyObj=new Proxy(obj,{
//获取值 target是目标对象 key是属性
get(target , key){
console.log(`检测到get`);
return target[key]
},
//设置值
set(target,key,newVal){
console.log("检测到set");
target[key] = newVal
},
//监听in 的操作符
has(target,key){
console.log("监听in操作");
return key in target
},
//监听delete
deleteProperty(target , key){
console.log("监听到delete操作");
delete target[key]
},
})
Reflect
ES6新增的内置对象
,所有方法都是静态方法,像Math
提供很多操作js对象的方法
,类似Object中操作对象的方法
- Reflect.getPrototypeOf(target) ~~ Object.getPrototypeOf()
- Reflect.defineProperty()~~ Object.defineProperty()
为什么要有这个对象
- 早期的规范中,没有考虑到对
对象本身操作
如何设计更加规范,于是将API放到了Object上面,导致Object类越来越臃肿,而它做为所有类的父类,会被继承到子类中,东西过多加重子类负担 - Object做为构造函数,将这些操作放在它上面不太合理
所以新增Reflect 来集中管理这些操作
set,get,has,deleteProperty,
getPrototypeOf,setPrototypeOf
对结果处理非常规范
- 操作失败一般返回false
- 操作成功返回值/true
let obj={
name:'zhangsan',
age:18
}
console.log("检查name属性是否存在",Reflect.has(obj,'name')); //检查name属性是否存在 true
console.log("获取name属性",Reflect.get(obj,'name'));//获取name属性 zhangsan
Reflect.set(obj,'name','lisi');
console.log(obj.name);//lisi
Reflect.deleteProperty(obj,'age');
console.log(obj.age);//undefined
console.log("检查age属性是否存在",Reflect.has(obj,'age')); //false
原文地址:https://blog.csdn.net/qq_73270720/article/details/145248128
免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!