JavaScript中拦截函数调用、修改函数执行行为的实现方法有哪些?
JavaScript 对象方法执行后置监听实现方案
你之前编写的Proxy代码未生效,是因为apply捕获器仅用于捕获代理函数的直接调用行为,代理普通对象时调用对象方法会先触发get捕获器,需要在get阶段对方法做包装。这里提供两种可行实现方案:
方案1:直接装饰原对象方法
该方案直接修改原对象的指定方法,逻辑简单直观,适合允许修改原对象的场景:
const ob = { doA() { console.log('a'); }, doB() { console.log('b'); } }; // 自定义的后置执行逻辑 const afterHook = () => { console.log('需要追加执行的代码'); }; // 批量包装指定方法 ['doA', 'doB'].forEach(methodName => { const originalMethod = ob[methodName]; ob[methodName] = function (...args) { // 先执行原有逻辑,保留this指向和参数传递 const result = originalMethod.apply(this, args); // 执行后置自定义逻辑 afterHook(); // 返回原方法的返回值,不影响原有逻辑的正常运行 return result; }; }); // 测试 ob.doA(); // 依次输出:a、需要追加执行的代码 ob.doB(); // 依次输出:b、需要追加执行的代码
方案2:Proxy 无侵入代理方案
该方案不会修改原对象的任何属性,适合不希望污染原对象的场景:
const ob = { doA() { console.log('a'); }, doB() { console.log('b'); } }; const afterHook = () => { console.log('需要追加执行的代码'); }; // 声明需要监听的方法列表 const watchMethodList = ['doA', 'doB']; const ob2 = new Proxy(ob, { get(target, property) { const targetValue = target[property]; // 仅对需要监听的函数做包装 if (watchMethodList.includes(property) && typeof targetValue === 'function') { return function (...args) { const result = targetValue.apply(this, args); afterHook(); return result; }; } // 其他属性正常返回 return targetValue; } }); // 测试代理对象 ob2.doA(); // 依次输出:a、需要追加执行的代码 // 原对象不受影响 ob.doA(); // 仅输出:a
内容的提问来源于stack exchange,提问作者user5507535
相关产品推荐
相关产品推荐

