描述:一个JS对象有属性有方法.现在希望对方法的调用进行侦听(将:调用的方法名, 参数, 结果进行记录), 类似java的AOP
设JS对象如下:
const tc={}
// 存放的数据
tc.data={}
// 以下是操作数据的方法
tc.method1=function(arg1){}
tc.method2=function(arg1,arg2){}
// ...
export default tc
描述:一个JS对象有属性有方法.现在希望对方法的调用进行侦听(将:调用的方法名, 参数, 结果进行记录), 类似java的AOP
设JS对象如下:
const tc={}
// 存放的数据
tc.data={}
// 以下是操作数据的方法
tc.method1=function(arg1){}
tc.method2=function(arg1,arg2){}
// ...
export default tc
不确定我是否理解正确,大概这样:
import sourceObj from './source-obj';
// 记录原始方法
const sourceMethod1 = sourceObj.method1;
// 替代为埋点后的方法
sourceObj.method1 = function(arg1) {
// 做你想触发的动作
console.log('method1 was called');
sourceMethod1.call(sourceObj, arg1);
}
// 导出新对象
export default sourceObj;
引用chatGPT
的回答:
为了对方法的调用进行侦听,可以使用JavaScript的Proxy对象。Proxy对象可以用于拦截函数调用,并在调用方法之前和之后执行自定义的方法。
下面是一个例子,展示如何使用Proxy对象来拦截函数调用并记录方法调用和返回值:
const tc = {}
// 存放的数据
tc.data = {}
// 用于记录方法调用和返回值的数组
tc.logs = []
// 以下是操作数据的方法
tc.method1 = function(arg1) {
const args = [arg1]
const result = () => {
// 在这里调用实际的方法
return `method1 result for ${arg1}`
}()
tc.logs.push({ name: 'method1', args, result })
return result
}
tc.method2 = function(arg1, arg2) {
const args = [arg1, arg2]
const result = () => {
// 在这里调用实际的方法
return `method2 result for ${arg1} and ${arg2}`
}()
tc.logs.push({ name: 'method2', args, result })
return result
}
// 创建一个代理对象,用来监听函数调用
const tcProxy = new Proxy(tc, {
// 拦截函数调用
apply: function(target, thisArg, argumentsList) {
// 获取函数名
const methodName = target.name
// 获取函数参数
const args = Array.from(argumentsList)
// 获取函数返回值
const result = thisArg[methodName].apply(thisArg, argumentsList)
// 记录日志
target.logs.push({ name: methodName, args, result })
return result
}
})
// 导出代理对象
export default tcProxy
在这个例子中,我们定义了一个新的属性logs作为记录方法调用和返回值的数组。然后,我们使用Proxy对象来创建一个代理对象tcProxy,用来监听函数调用。tcProxy对象实际上是一个对tc对象的包装,它包含了与tc相同的属性和方法。
在代理对象的apply方法中,我们拦截了函数调用,并获取了函数名、参数和返回值。然后,我们将这些信息记录到logs数组中。
使用代理的示例如下:
import tc from './tc.js'
tc.method1('arg1')
tc.method2('arg1', 'arg2')
console.log(tc.logs)
// 输出:
// [
// {
// "name": "method1",
// "args": ["arg1"],
// "result": "method1 result for arg1"
// },
// {
// "name": "method2",
// "args": ["arg1", "arg2"],
// "result": "method2 result for arg1 and arg2"
// }
// ]
在这个例子中,我们直接调用代理对象的方法而不是原始对象的方法,然后查看logs数组来检查方法调用是否被记录。我们可以看到,logs数组包含了method1和method2方法的调用记录,包括参数和返回值。
27 回答13k 阅读
8 回答3.5k 阅读✓ 已解决
6 回答1.3k 阅读✓ 已解决
5 回答5.3k 阅读✓ 已解决
4 回答1.6k 阅读✓ 已解决
6 回答1.1k 阅读
3 回答1.7k 阅读