js代理(Proxy)入门
1、什么是代理
正如大家所想的那样,没错,代理即代替。在javascript中Proxy就是在对象前面架设一层拦截,我们可以通过Proxy来访问这个对象的属性和方法。就跟对象的秘书一样,有事秘书干,没事秘书什么都不干_。
2、Proxy简单的使用
那proxy如何简单的使用呢,话不多说,直接上代码
let star = {
name: '迪丽热巴',
age: 18
}
let proxy = new Proxy(star,{
get(targetObj, propoty, receiver) {
console.log(`我是被代理的对象${targetObj}`)
console.log(`我是你访问的被代理的属性${propoty}`)
//receiver是代理对象proxy
return targetObj[propoty]
}
})
console.log(proxy.name)
这就是一个最简单的proxy的例子。 首先我们需要利用Proxy构造函数创建一个Proxy对象,我们需要向这个构造函数中传递两个参数,第一个参数是被代理的对象,第二个参数是一个捕获器对象。我们需要代理的所有行为都是在捕获器对象中定义的。
注意:只有当我们访问代理的时候才会被捕获,这时候我们仍然可以访问原来的对象,和设置捕获钱没有任何的变化
3、Proxy代理另一个代理
Proxy是可以设置多层代理的,即代理之上还有代理。就像我们说的那位苦命的秘书一样,其实她也是可以拥有秘书的。具体实现:
let proxyFirst = new Proxy(obj,{})
let proxySecond = new Proxy(proxyFirst,{})
我们通过proxySecond访问obj对象 的时候,不仅会触发他本身在捕获器对象中定义的捕获方法,还会触发proxyFirst 的。
我们通过proxyFirst 访问obj对象的时候,那么只会触发定义的在proxyFirst 身上的捕获方法。
4、捕获器中可以使用的方法
get()、set()、has、defineProperty()、getOwnPropertyDescriptor()、deleteProperty() 、ownKeys()、getPrototypeOf()、setPrototypeOf()、isExtensible()、preventExtensions()、construct()、apply()
捕获器有13种,这里我们重点介绍4种,即对象的增删改查。由于我们已经介绍过get()下面我们将介绍接下来的3个
- set()
set即设置,就是我们在设置对象属性的时候会捕获到。示例:
let proxy = new Proxy(star,{
set(targetObj, property, value, receiver) {
if(property == 'height') {
if(typeof value === 'number') {
return Reflect.set(targetObj, property, `${value+10}cm`)
}else {
throw '身高只能是数字类型的值'
}
}
}
})
proxy.height = 180
console.log(proxy.height)
在这个简单的示例当中,我们给star对象设置了一个代理,这个代理就是捕获在给star设置身高的时候,多加10cm。set()方法接收三个参数(目标对象,设置的属性,设置的值,proxy对象)
2、has()
has()即在查找的时候会被捕获,for…in ,has()代码如下:
let proxy = new Proxy(star,{
has(targetobj, property) {
return Reflect.has(...arguments)
}
})
proxy.height = 180
console.log('fansNums' in proxy)
has()捕获器接收两个参数,第一个参数是目标对象,第二个参数是引用的目标对象上字符串的属性。利用has捕获器,我们可以把不想让别人访问到的对象的属性隐藏掉。
- deleteProperty()
在我们删除属性的时候detete()捕获器会被触发。直接上代码:
let proxy = new Proxy(star,{
deleteProperty(targetobj, property) {
if(property === 'name') {
return false
}else {
return Reflect.deleteProperty(...arguments)
}
}
})
delete proxy.name
console.log(proxy.name)
5、创建可撤销的代理
const {proxy, revoke} = Proxy.revocable(star,{
get(targetObj, propoty, receiver) {
console.log(`我是被代理的对象${targetObj}`)
console.log(`我是你访问的被代理的属性${propoty}`)
//receiver是代理对象proxy
return targetObj[propoty]
}
})
// revoke()
console.log(proxy.name)
这和普通的创建proxy实例的方式有些区别,使用的是Proxy.revocable创建的代理。当我们不想使用此代理的时候可以使用revoke()直接将其删除即可。