首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

拿 Proxy 可以做哪些有意思的事儿

作者:贾顺名

segmentfault.com/a/1190000015009255

Proxy是什么

首先,我们要清楚,是什么意思,这个单词翻译过来,就是代理

可以理解为,有一个很火的明星,开通了一个微博账号,这个账号非常活跃,回复粉丝、到处点赞之类的,但可能并不是真的由本人在维护的。而是在背后有一个其他人 or 团队来运营,我们就可以称他们为代理人,因为他们发表的微博就代表了明星本人的意思。

P.S. 强行举例子,因为本人不追星,只是猜测可能会有这样的运营团队

这个代入到当中来,就可以理解为对或者的代理操作。

JavaScript中的Proxy

Proxy是ES6中提供的新的API,可以用来定义对象各种基本操作的自定义行为(在文档中被称为 ,我觉得可以理解为一个针对对象各种行为的钩子)。拿它可以做很多有意思的事情,在我们需要对一些对象的行为进行控制时将变得非常有效。

Proxy的语法

创建一个的实例需要传入两个参数

要被代理的对象,可以是一个 或者

对该代理对象的各种操作行为处理

在第二个参数为空对象的情况下,基本可以理解为是对第一个参数做的一次浅拷贝(Proxy必须是浅拷贝,如果是深拷贝则会失去了代理的意义)。

Traps(各种行为的代理)

就像上边的示例代码一样,如果没有定义对应的,则不会起任何作用,相当于直接操作了。

当我们写了某个以后,在做对应的动作时,就会触发我们的回调函数,由我们来控制被代理对象的行为。

最常用的两个应该就是和了。

早年有着在定义对象时针对某个属性进行设置、:

就像这段代码描述的一样,我们设置了一个属性,然后又设置了一个和。然后我们可以直接调用来获取一个返回值,也可以对其进行赋值。

这么做有几个缺点:

针对每一个要代理的属性都要编写对应的 、 。

必须还要存在一个存储真实值的 (如果我们直接在 里边调用 则会出现堆栈溢出的情况,因为无论何时调用 进行取值都会触发 )。

很好的解决了这两个问题:

我们通过创建、两个来统一管理所有的操作,可以看到,在修改的同时,的内容也被修改,而且我们对的行为进行了一些特殊的处理。而且我们无需额外的用一个来存储真实的值,因为我们在内部操作的是对象,而不是对象。

拿Proxy来做些什么

因为在使用了后,对象的行为基本上都是可控的,所以我们能拿来做一些之前实现起来比较复杂的事情。

在下边列出了几个简单的适用场景。

解决对象属性为undefined的问题

在一些层级比较深的对象属性获取中,如何处理一直是一个痛苦的过程,如果我们用可以很好的兼容这种情况。

我们代理了,并在里边进行逻辑处理,如果我们要进行的值来自一个不存在的,则我们会在中创建对应个这个,然后返回一个针对这个的代理对象。这样就能够保证我们的取值操作一定不会抛出。

但是这会有一个小缺点,就是如果你确实要判断这个是否存在只能够通过操作符来判断,而不能够直接通过来判断。

普通函数与构造函数的兼容处理

如果我们提供了一个对象给其他人,或者说一个版本的构造函数。

如果没有使用关键字来调用的话,对象会直接抛出异常,而中的构造函数指向则会变为调用函数时的作用域。

我们可以使用这个来兼容这种情况:

我们使用了来代理一些行为,在函数调用时会被触发,因为我们明确的知道,代理的是一个或构造函数,所以我们直接在中使用关键字来调用被代理的函数。

以及如果我们想要对函数进行限制,禁止使用关键字来调用,可以用另一个:。

用Proxy来包装fetch

在前端发送请求,我们现在经常用到的应该就是了,一个原生提供的API。

我们可以用来包装它,使其变得更易用。

对、进行了一层封装,可以直接通过这种方式来调用,并设置一些通用的参数。

实现一个简易的断言工具

写过测试的各位童鞋,应该都会知道断言这个东西。就是一个断言工具,接受两个参数,如果第一个为,则会将第二个参数作为抛出。

我们可以使用来做一个直接赋值就能实现断言的工具。

统计函数调用次数

在做服务端时,我们可以用代理一些函数,来统计一段时间内调用的次数。

在后期做性能分析时可能会能够用上:

全部的traps

这里列出了所有可以定义的行为(traps):

具体的可以查看MDN-Proxy里边同样有一些例子

参考资料

Magic Methods in JavaScript? Meet Proxy!

How to use JavaScript Proxies for Fun and Profit

MDN-Proxy

觉得本文对你有帮助?请分享给更多人

关注「前端大全」,提升前端技能

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180531B1QOCM00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券