实现原理:
- 通过Proxy(代理): 拦截对象中任意属性的变化, 包括:属性值的读写、属性的添加、属性的删除等。
- 通过Reflect(反射): 对源对象的属性进行操作。
- MDN文档中描述的Proxy与Reflect:
-
Proxy:Proxy - JavaScript | MDN
-
Reflect:Reflect - JavaScript | MDN
-
// 源数据
let person = {
name:'张三',
age:18
}
//模拟Vue3中实现响应式
const p = new Proxy(person,{
//有人读取p的某个属性时调用
get(target,propName){
console.log(`有人读取了p身上的${propName}属性`)
// 类似 return target[propName]
return Reflect.get(target,propName)
},
//有人修改p的某个属性、或给p追加某个属性时调用
set(target,propName,value){
console.log(`有人修改了p身上的${propName}属性,我要去更新界面了!`)
// 类似 target[propName] = value
Reflect.set(target,propName,value)
},
//有人删除p的某个属性时调用
deleteProperty(target,propName){
console.log(`有人删除了p身上的${propName}属性,我要去更新界面了!`)
// 类似 return delete target[propName]
return Reflect.deleteProperty(target,propName)
}
})
//对比 Object 和 Reflect
let obj = {a:1,b:2}
//通过Object.defineProperty去操作
//对同一属性多次操作会直接报错,导致运行不了下面的代码,必须加上try...catch 防止
/* try {
Object.defineProperty(obj,'c',{
get(){
return 3
}
})
Object.defineProperty(obj,'c',{
get(){
return 4
}
})
} catch (error) {
console.log(error)
} */
//通过Reflect.defineProperty去操作
//对同一属性多次操作不会直接报错,而是会返回true或false,不会影响下面的代码
/* const x1 = Reflect.defineProperty(obj,'c',{
get(){
return 3
}
})
console.log(x1)
const x2 = Reflect.defineProperty(obj,'c',{
get(){
return 4
}
})
if(x2){
console.log('某某某操作成功了!')
}else{
console.log('某某某操作失败了!')
} */
本文介绍了JavaScript中的Proxy和Reflect,用于实现对象的拦截与反射操作。通过Proxy可以监听对象属性的读取、修改和删除,实现响应式编程,如Vue3中的响应式原理。而Reflect提供了一种安全的操作对象属性的方式,相比Object.defineProperty,它在重复定义同一属性时不会抛出错误,而是返回操作结果。这两个特性在现代JavaScript开发中扮演重要角色。
841

被折叠的 条评论
为什么被折叠?



