js增加对象方法调用的侦听?

描述:一个JS对象有属性有方法.现在希望对方法的调用进行侦听(将:调用的方法名, 参数, 结果进行记录), 类似java的AOP

设JS对象如下:

const tc={}
// 存放的数据
tc.data={}
// 以下是操作数据的方法
tc.method1=function(arg1){}
tc.method2=function(arg1,arg2){}
// ...
export default tc
阅读 2.2k
4 个回答
✓ 已被采纳
const tc = {}

// 存放的数据
tc.data = {}

// 以下是操作数据的方法
tc.method1 = function (arg1) {
}
tc.method2 = function (arg1, arg2) {
}

const tcProxy = new Proxy(tc, {
    get(target, propKey, receiver) {
        // 如果是一个方法,就返回一个特定的方法
        if (typeof target[propKey] === 'function') {
            return function (...args) {
                // 这里就可以做自己想做的事,例如打印参数,方法名啥的都是可以的
                console.log(propKey, args)

                // 最后执行,用 Reflect 可以保证 this 指向
                return Reflect.apply(target[propKey], target, args)
            }
        }
            
        // 否则就直接获取属性就好了
        return Reflect.get(target, propKey, receiver)
    }
})

// 最后导出代理对象,用法是相同的
export default tcProxy

不确定我是否理解正确,大概这样:

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;

用javascript proxy 应该可以

引用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方法的调用记录,包括参数和返回值。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏