是否可以覆盖“call”函数?

9

是否可以在通用级别上覆盖“call”函数,以便在应用程序的任何地方调用方法时都会发生某些事情。

我尝试覆盖Object.call,虽然我成功了,但它并没有改变我的应用程序的工作方式。

顺便说一句,即使它起作用,我是否应该每次显式调用“foo.call(this,args)”,或者普通的函数调用也可以使用“foo(args)”?


你是否在考虑使用 Function.call?在 Object.prototype 上没有 call 方法。 - Ray Toal
也许你可以解释一下你真正想要实现什么。我认为你无法在JavaScript层面拦截每个JavaScript函数调用。你可能需要访问JS引擎内部的一些钩子才能做到这一点。 - jfriend00
2个回答

8
听起来你想在这里进行某种面向方面的编程....
JavaScript作为ECMAScript方言,确实有一个可调用对象的概念。每个可调用对象都有一个称为[[Call]]的内部属性。该属性在ECMA-262规范第5版的第8.6.2节表9中描述。它说:
执行与对象相关联的代码。通过函数调用表达式调用。SpecOp的参数是this对象和包含传递给函数调用表达式的参数的列表。实现此内部方法的对象是可调用的。只有返回引用值的主机对象才能调用。
但要注意的是[[Call]]是一个内部属性,规范说:
内部属性没有名称,并且不能通过ECMAScript语言运算符直接访问。内部属性仅出于规范目的而存在。
因此,您无法在自己的JavaScript代码中钩入此机制。
现在,Function.prototype中定义了两种方法:apply和call。如果更改Function.prototype.call的定义,则如果创建自己的函数f,则f.call将确实(除非在f的原型或f本身中被覆盖)执行该代码。这将不会通过直接调用f自动发生。您必须明确调用call方法。
尽管如此,在内置对象的原型中不要混淆预定义的标准方法。许多库和应用程序中的现有代码依赖于Function.prototype.call。不要搞砸它。当然,您可以以许多方式实现一种AOP行为。其中之一是向Function.prototype添加其他方法,但也不要这样做。另一种方法是编写自己的调用方法,并带有前后钩子:
function call(theThis, before, main, after, beforeArgs, mainArgs, afterArgs) {
    before.apply(theThis, beforeArgs);
    main.apply(theThis, mainArgs);
    after.apply(theThis. afterArgs);
}

我总是缓存原始调用函数的副本,并在最后调用它。 - user802232

0
换句话说,您想拦截应用程序中执行的任何函数调用?没有通用的方法可以做到这一点,至少目前还没有。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接