
深入解析:Object.defineProperty与Proxy结合引发的双重执行
本文将剖析Object.defineProperty和Proxy组合使用时,为何会触发两次执行的现象。以下代码片段将作为分析的基础:
const test = { querySelector() {}};Object.defineProperty(test, "querySelector", { get() { return new Proxy(document.querySelector, { apply(target, thisArgs, args) { console.log('test', thisArgs); return thisArgs.querySelector.apply(document, args); } }); }});// 执行代码test.querySelector("body");
运行上述代码,控制台会输出两次“test”,分别对应不同的thisArgs上下文。这正是我们试图解答的谜题:apply方法为何被调用两次?第一次thisArgs为何是{},第二次又是如何触发的?
关键在于thisArgs和get方法的返回值。
当第一次调用test.querySelector("body")时,Object.defineProperty定义的get方法被触发。在这个get方法内部,我们创建了一个Proxy对象,其apply方法记录了调用上下文thisArgs。此时,thisArgs指向test对象,即{},因此控制台第一次输出test {}。
然而,get方法的返回值是这个Proxy对象。 thisArgs.querySelector.apply(document, args)这行代码至关重要。它并非直接调用document.querySelector,而是通过thisArgs.querySelector(也就是test.querySelector)来调用。由于test.querySelector本身也是通过Object.defineProperty定义的,因此再次触发了get方法。
这次,thisArgs指向document对象,因为apply方法改变了上下文。所以控制台第二次输出test [object HTMLDocument]。document.querySelector.apply(document, args)最终完成了对querySelector方法的实际调用。
总结:
两次apply方法的调用并非因为document.querySelector内部再次调用自身,而是因为get方法的返回值是一个Proxy对象,并且在get方法内部使用了thisArgs.querySelector.apply,导致再次触发了get方法,从而产生了第二次apply调用。这突显了Object.defineProperty和Proxy结合使用时的复杂性,需要深入理解this上下文和apply方法的工作机制。 为了避免这种双重执行,建议重新设计代码逻辑,避免在get方法中再次调用自身属性。
以上就是Object.defineProperty与Proxy结合为何会触发两次执行?的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1503288.html
微信扫一扫
支付宝扫一扫