### 前言:
- 上一篇讲解了defineProperty方法今天来讲讲proxy
- vue3中数据劫持使用了proxy主要是因为defineProperty有几项缺点
- 新增属性,删除属性
- 直接通过下标修改数组
- defineProperty缺点讲解
```
//先回顾上期知识点
let person = {
name:'vike',
age:5
}
•
// 回顾上篇defineProperty方法
let p = {}
// name属性
Object.defineProperty(p,'name',{
get(){
console.log('读取name属性')
return person.name
},
set(newValue){
console.log('修改name属性')
person.name = newValue
}
})
// age属性
Object.defineProperty(p,'age',{
get(){
console.log('读取age属性')
return person.age
},
set(newValue){
console.log('修改age属性')
前言:
- 上一篇讲解了defineProperty方法今天来讲讲proxy
- vue3中数据劫持使用了proxy主要是因为defineProperty有几项缺点
- 新增属性,删除属性
- 直接通过下标修改数组
- defineProperty缺点讲解
//先回顾上期知识点 let person = { name:'vike', age:5 } // 回顾上篇defineProperty方法 let p = {} // name属性 Object.defineProperty(p,'name',{ get(){ console.log('读取name属性') return person.name }, set(newValue){ console.log('修改name属性') person.name = newValue } }) // age属性 Object.defineProperty(p,'age',{ get(){ console.log('读取age属性') return person.age }, set(newValue){ console.log('修改age属性') person.age = newValue } })
- 新增属性
- 没有进行数据劫持 不能成为响应式数据
- 删除属性
- 使用delete关键字删除属性,返回flase。
- delete 删除会返回true或者flase。删完了为true,删不掉为false
- 在Object.defineProperty配置项内多加一行configurable:true,即可删除
- delete删除p上属性不会影响person上的属性,主要原因是无法捕获这个变化
proxy讲解
- window.Proxy为内置函数
- 使用实例
let person = { name:'vike', age:5 } // proxy作用 让p映射person 第一个参数为要映射的对象 第二参数可为空对象占位 let p = new Proxy(person,{})
- Proxy里的Handler 对属性进行增删改查操作靠这里面的配置 - Proxy里的Target 属性 - 取值方法 p.name p.age - 新增 修改 删除 proxy代理实现
- proxy捕获数据 ``` // 源对象 let person = { name:'vike', age:5 } // 代理对象 let p = new Proxy(person,{ // get 上有两个参数 target是newProxy传入的对象 propName是读取的属性 // 读取属性触发 get(target,propName){ console.log(`读取了${propName}属性`) return target[propName] }, // set上新增了newValue属性 修改和新增触发 set(target,propName,newValue){ console.log(`修改了${propName}属性`) target[propName] = newValue }, // deleteProperty 删除属性触发 deleteProperty(target,propName) { console.log(`删除了${propName}属性`) delete target[propName] } }) ```
- delete p.name返回false是因为deleteProperty方法没返回,只要`return delete target[propName]` ### Reflect 介绍 - ES6新增 - ECMA正尝试把Object上的方法移植到Reflect上
- Reflect方法上也包含defineProperty 且有返回值 true表示成功,false表示失败 ``` let person = { name:'vike', age:5 } let p1 = Reflect.defineProperty(person,'sex',{ get() { return '男' } }) let p2 = Reflect.defineProperty(person,'sex',{ get() { return '女' } }) console.log(p1,p2) ```
- 对比Object.defineProperty 会直接报错且不执行下面代码 ``` let person = { name:'vike', age:5 } Object.defineProperty(person,'sex',{ get() { return '男' } }) Object.defineProperty(person,'sex',{ get() { return '女' } }) ```
总结
- Reflect和Object来说,框架封装更需要健壮性强的Reflect
- Proxy处理响应式数据更具优势
- Object.defineProperty那些缺点在vue框架里也提供了相应的api进行解决