使用 Function.prototype.apply 设置 javascript 回调范围

发布于 2024-10-25 17:12:13 字数 356 浏览 1 评论 0原文

每次在 JavaScript 中声明回调时都必须手动设置对象的范围,这很令人沮丧,但这是现实。我想知道是否可以通过传递 [mycallback].apply 作为回调,并将作用域对象作为参数来实现,如下所示:

var f = function() { console.log(this.x); };
var o = {x: 3};
setTimeout(f.apply, 1000, o);

据我所知,这应该以 o 作为作用域来调用 f,但 Chrome 给出了我“未捕获的类型错误:在 [object DOMWindow] 上调用了 Function.prototype.apply,它是一个对象而不是函数”。为什么这不起作用?

It's frustrating to have to manually set the scope of an object every time I declare a callback in JavaScript, but it's a fact of life. I wondered if I could do it by passing [mycallback].apply as the callback, and the scope object as an argument, like so:

var f = function() { console.log(this.x); };
var o = {x: 3};
setTimeout(f.apply, 1000, o);

As far as I can tell, this should call f with o as the scope, but instead Chrome gives me "Uncaught TypeError: Function.prototype.apply was called on [object DOMWindow], which is a object and not a function". Why doesn't this work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

眼泪也成诗 2024-11-01 17:12:13

出于同样的原因,您首先需要“设置范围”。只有apply函数被发送到setTimeout,它与函数f的关联丢失了。因此,Javascript 将全局对象 window 分配给 this,就像在任何其他情况下一样。

有趣的是,apply 虽然是一个本机函数,但在某些方面并不特殊或神奇,并且其行为方式与 this< 设置中用户定义的函数一致。 /代码> 变量。

For the same reason you need to "set the scope" in the first place. Only the apply function is sent to setTimeout, its association with function f is lost. Thus Javascript assigns the global object, window, to this, as it would in any other case.

It is interesting to note that apply, while being a native function, is not special or magical in some way, and behaves in a way consistent to user defined functions in the setting of the this variable.

苹果你个爱泡泡 2024-11-01 17:12:13

@MooGoo 的答案是正确的,但也许需要更多解释。

当您像这样在 f 上调用函数 apply 时:

f.apply(ctx, args);

...那么您就在 f< 的上下文中执行 apply /代码>。

但是,当您将对 apply 的引用传递给函数时,如下所示:

setTimeout(f.apply, 1000, o);

...这就是您所做的一切:传递对函数 f.apply 的引用。这相当于传递 Function.prototype.apply,因为:

console.log(f.apply === Function.prototype.apply); // true

f 的任何连接都会在 window.setTimeout 中丢失。它接收对 Function.prototype 的通用 apply 函数的引用。而已。没有上下文。

因此,与未设置显式上下文的任何其他情况一样,将使用 window 作为其上下文对象来调用 apply 函数。

@MooGoo's answer is correct, but perhaps more explanation is needed.

When you call the function apply on f like this:

f.apply(ctx, args);

...then you're executing apply in the context of f.

But when you pass a reference to apply to a function, like this:

setTimeout(f.apply, 1000, o);

...that's all you're doing: passing a reference to the function f.apply. This is equivalent to passing Function.prototype.apply because:

console.log(f.apply === Function.prototype.apply); // true

Any connection to f is lost in window.setTimeout. It receives a reference to the generic apply function of Function.prototype. Nothing more. No context.

Therefore, as in any other case where an explicit context is not set, the apply function is called with window as its context object.

幸福丶如此 2024-11-01 17:12:13

试试这个:

var f = function() { console.log(this.x); };
var o = {x: 3};
setTimeout(function(){f.apply(o)}, 1000);

对我有用。

设置超时需要一个函数。但由于 apply 是一个内置函数,并且您看不到它背后的本机代码,因此它可能无法充当“函数”对象。

Try this:

var f = function() { console.log(this.x); };
var o = {x: 3};
setTimeout(function(){f.apply(o)}, 1000);

Works for me.

Set timeout expects a function. But since apply is a built in function and you can not see the native code behind it, it may not act as a "function" object.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文