js的Proxy代理的基本使用
vue2.0是的数据响应式是基于Object.defineProperty的方式来实现的,到了vue3.0,尤雨溪就把它改成用Proxy代理的方式来实现数据响应式。Proxy的定义:代理的意思。就是你想要对数据进行操作,必须经过代理,让代理去帮你操作数据,你只需要对代理发号施令就可以了。相当于Proxy就是你的管家,你想买什么吃的,就跟管家说,管家会帮你去买。使用Proxy:const targe
·
vue2.0是的数据响应式是基于Object.defineProperty的方式来实现的,到了vue3.0,尤雨溪就把它改成用Proxy代理的方式来实现数据响应式。
Proxy的定义:代理的意思。就是你想要对数据进行操作,必须经过代理,让代理去帮你操作数据,你只需要对代理发号施令就可以了。相当于Proxy就是你的管家,你想买什么吃的,就跟管家说,管家会帮你去买。
使用Proxy:
const target = {
name: 'wjg',
age: 18
}
const proxy = new Proxy(target, {
get(target,prop) {
console.log('Get Value: ' + target[prop])
return target[prop]
// return target[prop] 等价于: return Reflect.get(target,prop)
},
set(target, prop, value) {
console.log('Set prop: ' + prop + ' to value:' + value)
target[prop] = value
// target[prop] = value 等价于: Reflect.set(target, prop, value)
}
})
console.log(proxy.name)
proxy.age = 19
console.log(proxy.age)
console.log(target.age)
解释:
- Proxy需要传进去两个参数,第一个你要代理的对象;第二个是handler,是你要对数据操作的一些方法。比如:get、set方法等等。
- 实例化Proxy会返回一个代理对象。以后我们想要对target这个对象进行操作的时候,就对代理对象proxy进行操作就行了,它会帮我们去操作target对象的。
- get方法的形参:第一个参数:要操作的对象;第二个参数:是你要操作的属性名。
- set方法的形参:第一和第二都和get方法的一样。第三个是你要设置的新的值。
- Reflect::映射。就是将对象的方法映射到Reflect这个对象。由于target[prop] = value这个操作有可能产生异常,而使用
Reflect.set(target, prop, value)
这个函数调用,它内部会帮我们try catch,操作失败它会返回一个fasle,就不至于导致程序异常。
与Object.defineProperty的区别:
- 都能够实现数据劫持
- Object.defineProperty是在原对象上进行数据劫持,而Proxy是对它返回的代理对象上进行数据劫持。
重写Proxy:
function deepClone(target) {
if(typeof target !== 'object' || target === null) {
return target
}
const res = target instanceof Array ? [] : {}
for(let key in target) {
if(target.hasOwnProperty(key)) {
if(typeof target[key] === 'object' && target[key] !== null ) {
res[key] = deepClone(target[key])
} else {
res[key] = target[key]
}
}
}
return res
}
function MyProxy(target, handler) {
const _target = deepClone(target)
Object.keys(_target).forEach(item => {
Object.defineProperty(_target, item, {
get() {
return handler.get && handler.get(target, item)
},
set(newVal) {
handler.set && handler.set(target, item, newVal)
}
})
})
return _target
}
const target = {
name: 'wjg',
age: 18
}
const proxy = new MyProxy(target, {
get(target, prop) {
console.log('Get Value: ' + target[prop])
return target[prop]
},
set(target, prop, value) {
console.log('Set prop: ' + prop + ' to value:' + value)
target[prop] = value
}
})
console.log(proxy.name)
proxy.age = 19
console.log(proxy.age)
console.log(target.age)
实现原理:
- 由于Proxy不是对原对象进行操作的,所以我们需要对目标对象进行深拷贝。
- 深拷贝完对拷贝完的对象的每一个属性进行重新定义,使用Object.defineProperty来操作。
- 在get方法中调用handler.get方法,但是传进去的是原对象target,set也是。所以就是我们操作代理里对象,让代理对象来帮我们去操作原对象。
- 记得返回被克隆的target对象
更多推荐
已为社区贡献3条内容
所有评论(0)