最近在开发我厂的 QA 工具时,遇到一个问题。我需要模拟 Puppeteer 的所有方法,以便兼容原先的 JS 文件。Puppeteer 提供一个 .asElement()
方法,可以把函数执行结果转换成一个伪 DOM Element(如果函数返回的就是 DOM Element 的话),然后我们就可以在 Node.js 里调用原本属于 DOM 的方法,比如 .focus()
。Pupputeer 会替我们完成映射和函数调用,并且返回结果。
对于大部分对象来说,我只要模拟对应的属性、方法,然后用自己的函数实现功能即可。但是 DOM Element 有上百个属性和方法,手工实现一遍实在太低效了。必须寻找其它途径。
好在我之前看过 Proxy 的介绍,赶紧翻出文档和书又复习两遍,就大概知道怎么做了。
Proxy 类如其名,可以“代理”对某个对象的访问。你可以把他理解成明星的经纪人。明星成名之前都是自己处理一切事务,有了经纪人之后,大部分事务就由经纪人负责,但仍然有一些事情需要明星自己处理。
Proxy 的用法很简单,实例化时,把要代理的对象传进去,定义一下代理方法就好。
const obj = { name: 'meathill' };
new Proxy(obj, {
get(target, property) {
// 如果对象中有要求的属性或方法,则返回
if (property in target) {
return target[property];
}
// 没有的话,进行其它处理
return 'hello';
}
});
obj.name // 'meathill'
obj.age // 'hello'
obj.sex // 'hello'
接下来,比如我们访问 obj.foo
,那么代理就会生效,它会先检查 obj
,如果这个对象上本来就有 foo
属性,就会返回;如果没有,则会调用我们定义的方法来处理。
如此一来,我们可以定义一个 VElement 类,这个类可以实现一些特殊方法,比如 .type(str)
输入,.click()
点击等;然后用 Proxy 代理其它方法和属性,让对象进入插件 Context 执行。
关于如何创建具有魔法属性/方法的类,请移步阅读 使用 Proxy 创建有魔术属性/方法的类
Proxy 还有其它方法也很有用,尤其是 get
对应的 set
,以后再介绍。大家可以自己抽空研究下。
参考
- 阮一峰的 ES6
- 《深入理解 ES6》
欢迎吐槽,共同进步