You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js中函数Proxy的apply方法未被调用,求解决方法

问题分析与解决方案

嗨,我一眼就看出问题所在啦——你用Proxy的apply陷阱时,搞错了代理的目标类型!

核心问题:apply陷阱只对函数生效

你现在的代码里,Object.assign({}, Magic.Foo)返回的是一个普通对象(哪怕这个对象里包含函数属性),而Proxy的apply陷阱只有当代理的目标本身是函数的时候,才会在调用这个函数时被触发。普通对象根本不会触发apply陷阱,这就是为啥你的代码里那个handler从来没执行过。

修正方案

根据你的需求,有两种常见的解决思路:

1. 直接代理目标函数

如果你想拦截的是Foo.runme这个函数的调用,直接把Proxy套在这个函数上就行:

var Foo = { runme: function() { return 1; } };
var Magic = { Foo: Foo };

// 给runme函数套上Proxy
Magic.Foo.runme = new Proxy(Magic.Foo.runme, {
  apply(target, thisArg, argumentsList) {
    console.log("apply陷阱被触发了!");
    // 调用原函数并返回结果
    return target.apply(thisArg, argumentsList);
  }
});

// 现在调用runme就会触发陷阱啦
console.log(Magic.Foo.runme()); // 先输出"apply陷阱被触发了!",再输出1

2. 代理对象,动态拦截函数调用

如果你想代理整个Foo对象,同时自动拦截对象里所有函数的调用,可以用get陷阱来实现:

var Foo = { runme: function() { return 1; } };
var Magic = { Foo: Foo };

Magic.Foo = new Proxy(Magic.Foo, {
  get(target, propName) {
    const value = target[propName];
    // 如果取到的是函数,就给它套上带apply陷阱的Proxy
    if (typeof value === 'function') {
      return new Proxy(value, {
        apply(targetFn, thisArg, args) {
          console.log(`函数${propName}被调用,参数:${args}`);
          return targetFn.apply(thisArg, args);
        }
      });
    }
    // 非函数属性直接返回原 value
    return value;
  }
});

// 调用runme时会触发动态生成的Proxy的apply陷阱
Magic.Foo.runme(); // 输出"函数runme被调用,参数:"和1

总结一下

记住Proxy的各个陷阱都是有触发条件的:apply专门负责拦截函数调用行为,所以必须保证代理的目标是函数本身,而不是包含函数的普通对象。这样调整后,你的代码就能正常触发apply陷阱啦!

内容的提问来源于stack exchange,提问作者Dave Stein

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:24:23