前言
需求:想要监听对象中属性被设置或者获取的过程
可以通过ES6中的属性描述符Object.defineProperty来实现具体操作如下:
const boy = {
name: "sabo",
age:14
}
Object.keys(boy).forEach(key => {
let value = boy[key]
Object.defineProperty(obj,key,{
get:function(value){
console.log(`监听到obj对象的${key}属性被访问了`)
return value
},
set:function(newValue){
console.log(`监听到obj对象的${key}属性被设置值`)
value = newValue
}
})
})
boy.name ="aaa"
boy.age = 18
但是如此操作会出现一些问题,最初的boy对象的属性描述符是数据属性描述符,但是为了监听数据的变化在内部调用了get 和 set 方法 属性描述符从原来的数据属性描述符变成了存储属性描述符。
如果我们想监听更加丰富的操作,比如新增属性、删除属性,那么Object.defineProperty是无能为力的
Proxy基本使用
在ES6中,新增了一个Proxy类,这个类从名字就可以看出来,是用于帮助我们创建一个代理的: 也就是说,如果我们希望监听一个对象的相关操作,那么我们可以先创建一个代理对象(Proxy对象); 之后对该对象的所有操作,都通过代理对象来完成,代理对象可以监听我们想要对原对象进行哪些操作;
const boy = {
name: "sabo",
age:14
}
const newObj = new Proxy(obj,{
set:function(target,key,newValue){
console.log(`监听到对象的${key}`)
target[key] = newValue
}
})
newObj.name = "aaa"
Proxy的捕获器
我们想要侦听对象的某些具体的操作,那么就可以在handler中添加对应的捕捉器(Trap)
- handler.getPrototypeOf() Object.getPrototypeOf 方法的捕捉器。
- handler.setPrototypeOf() Object.setPrototypeOf 方法的捕捉器。
- handler.isExtensible() Object.isExtensible 方法的捕捉器。
- handler.preventExtensions() Object.preventExtensions 方法的捕捉器。
- handler.getOwnPropertyDescriptor( )Object.getOwnPropertyDescriptor 方法的捕捉器。
- handler.defineProperty() Object.defineProperty 方法的捕捉器。
- handler.ownKeys() Object.getOwnPropertyNames 方法和 Object.getOwnPropertySymbols 方法的捕捉器。
- handler.has() in 操作符的捕捉器。
- handler.get() 属性读取操作的捕捉器。
- handler.set() 属性设置操作的捕捉器。
- handler.deleteProperty() delete 操作符的捕捉器
- handler.apply() 函数调用操作的捕捉器。
- handler.construct() new 操作符的捕捉器
Reflect的作用
Reflect也是ES6新增的一个API,它是一个对象,字面的意思是反射
那么这个Reflect有什么用呢?
它主要提供了很多操作JavaScript对象的方法,有点像Object中操作对象的方法;
比如Reflect.getPrototypeOf(target)类似于 Object.getPrototypeOf();
比如Reflect.defineProperty(target, propertyKey, attributes)类似于Object.defineProperty() ;
Reflect的使用
const obj = {
name: "sabo",
age: 18
}
const objProxy = new Proxy(obj, {
get: function(target, key, receiver) {
console.log("get---------")
return Reflect.get(target, key)
},
set: function(target, key, newValue, receiver) {
console.log("set---------")
target[key] = newValue
const result = Reflect.set(target, key, newValue)
if (result) {
} else {
}
}
})
objProxy.name = "aaa"
console.log(objProxy.name)
携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情