是否可以覆盖“呼叫”?功能? [英] Is it possible to override the "call" function?

查看:67
本文介绍了是否可以覆盖“呼叫”?功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以在通用级别覆盖调用函数,以便每次在应用程序的任何位置调用某个方法时,都会发生一些事情。

Is it possible to override the "call" function on a generic level, so that every time when a method gets called anywhere in the app, something happens.

我尝试重写Object.call,但是虽然我设法做到了,但它没有改变我的应用程序的工作方式。

I tried overriding Object.call, but although I managed to do it, it didn't change anything in the way my app works.

BTW,即使它有效,我应该每次都明确地调用foo.call(this,args),否则正常的函数调用也会起作用foo(args)?

BTW, even if it works, should I explicitly call "foo.call(this,args)" every time, or normal function calls will also work "foo(args)" ?

推荐答案

听起来你想在这里做一些面向方面的编程....

Sounds like you want to do some kind of aspect oriented programming here....

JavaScript,作为ECMAScript方言,确实有这个概念可调用对象。每个可调用对象都有一个名为 [[Call]] 内部属性。该属性在ECMA-262规范第5版的第8.6.2节表9中描述。它说:

JavaScript, as an ECMAScript dialect, does have the notion of a callable object. Every callable object has an internal property called [[Call]]. This property is described in Section 8.6.2, Table 9, of the ECMA-262 Specification, 5th edition. It says:


执行与该对象关联的代码。通过函数调用表达式调用。 SpecOp的参数是一个this对象和一个包含传递给函数调用表达式的参数的列表。实现此内部方法的对象是可调用的。只有作为宿主对象的可调用对象才能返回参考值。

Executes code associated with the object. Invoked via a function call expression. The arguments to the SpecOp are a this object and a list containing the arguments passed to the function call expression. Objects that implement this internal method are callable. Only callable objects that are host objects may return Reference values.

但需要注意的是 [[Call]] 是一个内部属性,规范说明:

But the thing to be aware of is that [[Call]] is an internal property, for which the spec says:


内部属性没有名称,不能通过ECMAScript语言操作员直接访问。内部属性纯粹出于规范目的而存在。

An internal property has no name and is not directly accessible via ECMAScript language operators. Internal properties exist purely for specification purposes.

所以你不能在你自己的JavaScript代码中挂钩这个机制。

So you can not hook into this mechanism in your own JavaScript code.

现在 Function.prototype 中定义了两种方法, apply 致电。确实,如果您更改 Function.prototype.call 的定义,那么如果您创建自己的函数 f ,那么 f.call 确实会(除非在f的原型或f本身中被覆盖)执行该代码。正如您所假设的那样,这不会直接通过调用 f 自动发生。你必须明确地调用调用方法。

Now there are two methods defined in Function.prototype, apply and call. It is true that if you change the definition of Function.prototype.call then if you create your own function f, then f.call will indeed (unless overridden in f's prototype or in f itself) execute that code. This will, as you presumed, NOT automatically happen by calling f directly. You have to explicitly call the call method.

所有这一切,最好不要使用预定义,内置对象原型中的标准方法。库和应用程序中的许多现有代码依赖于 Function.prototype.call 。不要乱用它。当然,您可以通过多种方式实现一种AOP行为。一种是添加 Function.prototype 其他一些方法,但不要这样做。另一个是用挂钩前后编写自己的调用方法:

All that said, it is best not to muck with predefined, standard methods in the prototypes of built-in objects. A lot of existing code in libraries and applications depend on Function.prototype.call. Don't mess with it. You can, of course, implement a kind of AOP behavior in many ways. One is to add to Function.prototype some other method, but don't do this either. Another is to write your own call method with before and after hooks:

function call(theThis, before, main, after, beforeArgs, mainArgs, afterArgs) {
    before.apply(theThis, beforeArgs);
    main.apply(theThis, mainArgs);
    after.apply(theThis. afterArgs);
}

这篇关于是否可以覆盖“呼叫”?功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆