使用代理捕获函数调用不会拦截参数

问题描述 投票:0回答:1

我想拦截函数调用,发现代理可以使用 apply 方法来实现这一点,如 MDN 所示。但是我很快发现传递给函数的参数不会被拦截,因此如果您的参数可以是表达式,例如标记模板文字的情况,例如 apply 方法不会拦截标记模板的执行,并且它`s 表达式,为什么会这样?除了创建包装函数之外还有什么方法可以做到这一点?我认为参数应该被拦截,对我来说,这也像是代理实现中的一个错误。

// create tagged template function
function template(strings, ...keys) {
 console.log("tmp fn");
 
  return (...values) => {
    const dict = values[values.length - 1] || {};
    const result = [strings[0]];
    keys.forEach((key, i) => {
      const value = Number.isInteger(key) ? values[key] : dict[key];
      result.push(value, strings[i + 1]);
    });
    return result.join("");
  };
}

// Trapping a function call with proxy 
const taggedTemplate = new Proxy(template, {
  apply(target, thisArg, argArray) {
    console.log("apply");
    return target(...argArray)
  }
});

// some fn for the template
function Num() {
 console.log("Not intercepted Num() call")
 return 5
};

// use template
taggedTemplate`my fav number is ${Num()}`

javascript es6-proxy
1个回答
0
投票

我想拦截函数调用,发现代理可以做到这一点

太复杂了。您所需要的只是一个包装函数:

// Trapping a function call with another function
const taggedTemplate = (...argArray) => {
  console.log("apply");
  return target(...argArray);
};

代理在这里没有实现任何其他功能。

我很快发现传递给函数的参数没有被拦截。这是为什么?

因为只有

taggedTemplate
是代理(或包装函数),并且当调用特定的
apply
函数对象时,会触发
taggedTemplate
陷阱。
Num()
不涉及任何代理。表达
taggedTemplate`my fav number is ${Num()}` 
与做

没有什么不同
const value = Num();
taggedTemplate`my fav number is ${value}`

有什么办法可以做到吗?

没有。

© www.soinside.com 2019 - 2024. All rights reserved.