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