js的Proxy代理对象?看完你就会了

更新日期: 2021-06-12阅读: 1.6k标签: 代理

什么是Proxy代理?

// pOjb就是通过new Proxy创建的代理对象
var pObj = new Proxy(obj, handlers)


为什么需要代理对象

举个记账的例子:

// obj代表我们,wallet属性指我们钱包,现在我们钱包里有100元
// consume指消费次数,每次消费加1, 记一笔账
var obj = {wallet: 100}
var consume = 0

// 这个月,我们喝了五次肥宅快乐水,每次消费我们都记一笔

// 今天消费3元
consume++
obj.wallet = 97

// 今天消费3元
consume++
obj.wallet = 94

// 今天消费3元
consume++
obj.wallet = 91

// 今天消费3元
consume++
obj.wallet = 88

// 今天消费3元
consume++
obj.wallet = 85

每次我们修改钱包剩余金额时,都要执行一次consume++去执行一次记账的操作。有没有更简单的方式,不需要每次都写上一行代码去增加消费次数呢?

答案当然有,它就是Proxy代理对象!使用代理对象,你想对目标对象的属性操作全部改为对代理对象相同属性的操作,代理对象提供了对属性获取 [[get]] 修改 [[set]] 等操作的拦截,js将这种拦截称为trap(捕捉器)。

通过捕捉器,我们就可以捕获到 代码中对属性的操作时机,让我们能够先执行我们自定义的业务逻辑代码。因为我们对目标对象的属性操作改为了对代理对象相同的属性操作,所以我们在最后需要通过Reflact执行目标对象的原始操作。

var consume = 0
// 目标对象
var obj = {wallet: 100}
// 捕获器trap
var handlers = {
	set(target, key, val) {
		// target 目标对象
		// key 代理对象要修改的属性
		
		// 记录一笔消费
		consume++
		// 通过Reflact对象触发原始目标对象的属性操作
		// 相当于执行 target[key] = val
		Reflect.set(target, key, val)
	}
}
// 代理对象
var pObj = new Proxy(obj, handlers)
// 将对目标对象obj的属性wallet操作改为代理对象相同属性wallet的操作
pObj.wallet = 97
pObj.wallet = 94
pObj.wallet = 91
pObj.wallet = 88
pObj.wallet = 85

console.log(obj.wallet) // 85
console.log(consume) // 5


如何取消代理

假如某一天,你实现了财务自由,不需要再精打细算记录每一笔消费了,你可能就需要取消此前的代理,代码很简单,往下看:

var consume = 0
var obj = {wallet:  100}
var handlers = {
	set(target, key, val) {
		consume++
		Reflect.set(target, key, val)
	}
}

// 使用Proxy.revocable创建代理
var tmpObj = Proxy.revocable(obj, handlers)
var pObj = tmpObj.proxy
var prevoke = tmpObj.revoke

// 使用代理对象进行消费记账
pObj.wallet = 97
pObj.wallet = 94
pObj.wallet = 91

// 某一天,我们实现了一个小目标
pObj.wallet = 100000000
// 我们不需要记账了,我们需要取消创建的代理
prevoke() // 执行prevoke即可,就是这么简单 哦耶~

pObj.wallet = 99999997 // TypeError 报错啦 (代理取消之后就不能使用了哟!)


代理在后模式

前面的示例都是先执行代理捕获器中的业务逻辑,最后再通过Reflect执行目标对象的属性操作,这种捕获代码操作在前,目标对象操作在后的模式称为“代理在先”模式,有在先,当然就有在后模式。

当然这里的“代理在后”模式并不是先使用Reflect对象触发目标对象属性操作,在执行捕获器中的其他操作代码。而是指代理作为目标对象的一种补充,我们仍然操作的是目标对象,只是当某些操作在目标对象上无法实现时,才使用代理对象。

等会,当某些操作目标对象无法提供时,js会向目标对象的原型prototype上进行查找,所以“代理在后”模式是对目标对象的原型进行代理!

var handlers = {
	get(target, key, context) {
		return function () {
			context.speak(key + '!')
		}
	}
}

var catchall = new Proxy({}, handlers)

var greeter = {
	speak(who = 'someone') {
		console.log('hello ', who)
	}
}

// 将catchall设置为greeter的原型
Object.setPrototypeOf(greeter, catchall)

greeter.speak() // hello someone
greeter.speak('world') // hello world

// 执行greater上不存在的方法
greeter.everyone() // hello everyone!


Reflect

Reflect对象用来触发目标对象执行相应的操作,就是这么简单!

Reflect.get(target, key, context) // 等价于  target[key]
Reflect.set(target, key, val) // 等价于 target[key] = val

链接: https://fly63.com/article/detial/10419

什么是在线代理ip网页代理

当我们需要大量IP进行快节奏完成业绩的时候,很多人都会想到去IP代理服务商那里购买IP代理,所以我相信很多人对于IP代理这个词已经有一定的认识了,那么还有一个词叫做:在线代理ip网页代理

centos7下搭建高匿HTTP代理

一般适用情况:1、两台都有外网IP,一台服务器请求资源通过另外一个服务器,本文重点讲第一种。2、两台服务器,其中一台服务器只有内网IP,另外一台服务器有公网和内网IP。

.Net Core/Framework之Nginx反向代理后获取客户端IP等数据探索

公司项目最近出现获取访问域名、端口、IP错误现象,通过排查发现, 之前项目一直通过Nginx自定义Headers信息来获取,但最近运维人员失误操作造成自定义Header信息丢失,造成项目拿不到对应的数据。

反向代理和内网穿透

反向代理看上去看深奥,其实不然,只是因为汉语言文化的差异导致它看上去深奥。一般反派感觉都比较厉害和神秘。要理解反向代理,我们就不得不说一下正向代理。正向代理代理的对象是客户端;反向代理代理的对象是服务端

反向代理Cloudflare加速网站(SNIproxy)

写在教程前:为什么要反向代理cloudflare?答:缩短路由,加快cloudflare节点到大陆用户的速度,用过cloudflare的用户应该知道,这家CDN的速度在除了大陆以外的地方访问都非常快,那么又没有什么办法使其对大陆访问良好呢?

ES6中的代理(Proxy)和反射(Reflection)

调用 new Proxy() 可常见代替其它目标 (target) 对象的代理,它虚拟化了目标,所以二者看起来功能一致。代理可拦截JS引擎内部目标的底层对象操作,这些底层操作被拦截后会触发响应特定操作的陷阱函数。

Vue多环境代理配置

多人协作模式下,修改代理比较麻烦,而且很容易某个开发人员会修改了vue.config.js文件后提交了。第一,很容易引起冲突。 第二,很容易出现代理错误,需要排查。而且现在微服务盛行

node.js代理访问

本地开发,代理访问,防止跨域(一般通过webpack配置代理即可),特殊情况如携带一些自定义的登录cookie则需要通过自己写node,作为一种server中间层,单线程异步可以缓解服务器压力

vue proxy代理跨域

changeOrigin的属性值为一个布尔值,如果设置为true,那么本地会虚拟一个NODE服务端接收你的请求并代你发送该请求(中间件)。[本质上是本地开了一个服务器dev-server,所有的请求都通过这里转发出去。]

Nginx反向代理之动静分离

我们已经知道了什么是正向代理与反向代理,这次我们就讲一下Nginx的动静分离的案例,其实质运用的就是反向代理,专门用一台服务器代理服务器上的图片资源。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!