如何在ES6 Proxy完成get操作序列后执行函数并记录访问路径?
捕获嵌套Proxy链式访问的完整路径
这个问题挺有意思的——要在嵌套Proxy的链式访问完成后捕获完整路径,而不是每次get触发时就输出中间步骤对吧?我之前也遇到过类似的场景,分享一个可行的实现思路:
核心思路是利用闭包跟踪当前访问路径,结合**微任务(queueMicrotask)**来判断链式访问是否结束:每次触发get陷阱时,我们会构建新的路径,然后通过微任务在同步代码执行完毕后检查这条路径是否是当前的最终路径——如果是,就输出它;如果后续还有属性访问(更新了当前路径),就跳过中间路径的输出。
完整实现代码
function createPathTrackingProxy(target) { let currentPath = []; const handler = { get(target, prop, receiver) { // 跳过Symbol类型的属性,避免干扰内部方法(比如toString) if (typeof prop === 'symbol') { return Reflect.get(target, prop, receiver); } // 构建当前访问的完整路径 const newPath = [...currentPath, prop]; // 更新当前活跃的路径 currentPath = newPath; // 获取目标属性的原始值 const value = Reflect.get(target, prop, receiver); if (value !== null && typeof value === 'object') { // 如果是嵌套对象,返回新的Proxy继续跟踪 queueMicrotask(() => { // 只有当这条路径还是当前活跃路径时,才输出(说明没有后续访问) if (JSON.stringify(currentPath) === JSON.stringify(newPath)) { console.log('已记录访问路径:', newPath); } }); return createPathTrackingProxy(value); } else { // 如果是原始值,直接输出完整路径(链式访问结束) console.log('已记录访问路径:', newPath); return value; } } }; return new Proxy(target, handler); }
测试示例
// 创建带路径跟踪的嵌套对象Proxy const trackedObj = createPathTrackingProxy({ shallow: { deep: '最终值' }, foo: { bar: { baz: 456 } } }); // 测试链式访问 trackedObj.shallow.deep; // 同步执行完毕后输出:已记录访问路径: ["shallow", "deep"] trackedObj.foo.bar.baz; // 同步执行完毕后输出:已记录访问路径: ["foo", "bar", "baz"]
工作原理说明
- 闭包维护路径:每个Proxy实例通过闭包共享
currentPath变量,每次访问属性时都会基于当前路径构建新路径并更新currentPath。 - 微任务判断结束:当返回嵌套对象的Proxy时,我们通过
queueMicrotask添加一个异步任务——这个任务会在当前同步代码块执行完毕后运行,此时如果currentPath和当前构建的newPath一致,说明没有后续的属性访问,这条路径就是完整的链式访问路径,我们就输出它。 - 原始值直接输出:如果访问的是原始值(字符串、数字等),链式访问直接结束,我们可以立即输出完整路径。
这样就完美解决了“每次链式访问完成后记录完整路径”的需求,不会输出中间的shallow或foo.bar这类半路径。
内容的提问来源于stack exchange,提问作者jonny
相关产品推荐
相关产品推荐

