我如何使用 ES6 代理创建一个验证库
我如何使用 ES6 代理创建一个验证库
原文:https://medium.com/hackernoon/how-i-made-a-validation-library-using-es6-proxy-59df82c1a4c0

Photo taken by me @ San Juan de Gaztelugatxe. (CC BY-NC-SA 3.0)
主流浏览器中的代理支持已经出现,是时候释放它带来的所有力量了。
TLDR;如果你只是想检查代码,你可以在下面的 github 链接上找到它。如果你只是想看看验证器的运行情况,那就走到最后。
代理验证器——利用 ES6 代理的能力来验证和清理对象的小软件包。
github.com](https://github.com/sorodrigo/proxy-validator)
完全披露:我在 8 月 28 日开始写这篇博客,然后我被一些事情缠住了,没有完成。现在我回来完成我开始的事情。
我已经想了一会儿,我在 MDN 上偶然发现的这个代理是什么东西。我看了很多遍描述和 API。然而,我不太清楚我可以利用它的用例是什么。
不管怎样,一个周末我花了一些时间去深入研究它,读了一些博客文章,并决定尝试一下。
那么什么是代理呢?
如果你问 Mozilla 用户,他们可能会说:
代理对象用于定义基本操作的自定义行为(如属性查找、赋值、枚举、函数调用等)。
换句话说,当与一个对象发生交互时,你可以让事情发生。多亏了陷阱,这才成为可能,不过我们稍后会详细讨论这个问题。
要创建新的代理,必须提供一个目标和一个处理程序。正如 MDN 所说,目标可以是任何类型的对象(即对象、数组、函数或代理)。这是将遭受与代理交互的最终副作用(如果有的话)的一方。
处理程序是另一个定义陷阱的对象。陷阱是函数,设置为在代理上执行操作时动作。根据操作的不同,会调用这样或那样的陷阱。我喜欢把陷阱看作某种生命周期挂钩。如果你使用过前端框架(比如 React),这就不是什么新鲜事了。对其他人来说——真的吗?—生命周期挂钩是在…aaaa 组件生命周期的某一点调用的回调?什么东西?不管怎样。
我说到哪了?当然是代理陷阱。例如,如果你想在组件挂载时执行一些代码,你需要实现componentdimount钩子,对吗?对吗?嗯,有了代理,你可以做(几乎)同样的事情!
在处理程序中实现构造陷阱,每次创建代理对象的新实例时,您的代码都会执行!
假设您想要添加一个钩子,当目标的一个属性是:
- 分配?使用设置陷阱。
- 读书?使用获取陷阱。
- 移除?使用删除属性陷阱。
- 结婚了?我不认为有一个,但是嘿!谁知道!
用代理验证对象
当我在记录代理和它们的用法时,我偶然发现了一个使用代理进行验证的例子。实现看起来非常简单,我认为它可以成为一个非常常见的用例——所以管它呢——我开始编写一个小型库。
因为我不想重新发明轮子,所以我决定使用现有的库进行所有的验证。这让我可以专注于 ES6 代理部分,也有一个更广泛、更好、测试更好和维护更好的验证。全拜 validator.js 所赐;如果你使用 JS 验证库,你很可能正在使用它。如果你不是,去看看这里的。
构建流程
像往常一样,我的第一步是设置构建过程。为此我选择了 Rollup.js 。这个配置非常简单,而且是专门为构建发行版代码而设计的。
设计决策
正如我们之前看到的,要创建一个代理,我们需要两样东西:一个处理程序和一个目标。这很酷,但是验证呢?如果我们要验证一个对象内部的属性,我们需要一个验证模式。这个验证模式应该将每个属性映射到一组分配的值应该遵循的规则。
目前我们知道些什么?我们需要一个处理程序、一个目标和一个验证模式。
但是你猜怎么着!?我们选择了这个很棒的库来处理验证,它也支持消毒。那么为什么不把它加入到组合中呢?这可以用与验证相同的方式来处理,但是我们需要提供一个单独的模式,一个净化模式。

Two schemas, the handler and the target.
validator.js 包装器
我不太记得我为什么先开始写这部分代码,但我怀疑是因为它更熟悉。
知道我有一套规则来测试一个赋值;我的第一步是创建一个执行测试并返回结果的函数。测试可能成功,也可能失败。仅仅返回测试是否通过是不够的。正确的验证需要告诉用户哪里出错了,这意味着还应该返回一个错误对象。 从这个意义上说,净化要简单得多,我只需要将净化规则应用到输入中,并返回最终结果。
弄脏我的手
好了,验证已经设置好并运行了,让我们代理一下。
我们需要的是一个接收验证模式、可选的净化模式和目标的函数。然后返回一个代理对象。
这意味着用户每次想要创建一个经过验证的对象时,都需要传递模式。这会很快变得很尴尬。那么为什么不分成两步呢?
我们将创建一个创建处理程序对象的工厂函数,然后返回另一个创建代理对象的工厂函数。
工厂异常
换句话说,我们有一个创建验证器的函数,每个验证器创建一个验证代理对象。
As you can see the actual implementation of the proxy is very small.
使用代理验证器
假设我们正在创建一个联系人列表,我们想验证一些字段,我们该怎么做呢?很简单,我们定义相应的 ContactValidator 模式并创建我们的 withValidation 代理。
关于代理的更多信息
Sindresorhus 最近发布了一个很酷的代理观察者:
on-change -观察对象或数组的变化
github.com](https://github.com/sindresorhus/on-change)
您可以在以下帖子中找到更多关于 ES6 代理的信息:
代理是 ES6 中一个非常有趣的特性。简而言之,您可以使用代理来决定行为…
ponyfoo.com](https://ponyfoo.com/articles/es6-proxies-in-depth) [## ES6 功能-代理的 10 种使用情形
今天我们来看看代理的可能用例,这是 ES6 的特性之一。源代码可以在 GitHub 上找到,在…
dealwithjs.io](http://dealwithjs.io/es6-features-10-use-cases-for-proxy/)