没有参数的 .call() / .apply() 与简单使用 () 括号调用函数的区别

7

我看到一些代码中使用了不同的方式,但是使用空参数的.call / .apply与普通的()函数执行相比有什么好处或原因呢?

当然,这只是一个过于简化的例子。

var func = function () { /* do whatever */ };

func.call();
func.apply();

与普通的圆括号相比,VERSUS 更加复杂。
func();

我在任何地方都没有看到关于这个的信息,我知道为什么要在传递参数时使用call/apply。


3
@FeistyMango:绝对不是那个的复制品。 - Jon
你在哪里看到这样的代码?我曾经认为(并回答)它是为了确保this为空,但事实并非如此。通过一些快速实验,据我所知,这是一个毫无意义的做法。 - Pointy
他在询问使用没有this参数的.call.apply与直接调用函数的原因。 - Bart
@FeistyMango 我把这两个放在同一类别中,我更关注的是为什么有人会使用空参数 funcName.call(); 而不是 funcName(); - Mark Pieszak - Trilon.io
@FeistyMango看一下问题——他正在询问是否可以使用.call().apply()中的任意一个而不带参数,而不是直接调用函数。 - Pointy
显示剩余2条评论
2个回答

6
当您使用func();调用方法时,方法内部的this变量指向window对象。
而当您使用call(...)/apply(...)时,传递给方法调用的第一个参数将成为方法内部的this。如果您未传递任何参数/传递null或undefined,则this将在非严格模式下变成全局对象

2
不,this 仍然会指向全局对象,除非你明确将 undefined 作为第一个参数传递。 - Bart
1
Bart是正确的 - 实际上,即使您明确传递null或undefined,this也将是window。在“严格”模式下它可以工作,但是然后只有普通的func()也会将this设置为undefined - Pointy
1
@Bart 是的,你是对的 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/call - Arun P Johny
哇,非常有趣,绝对值得知道!也许我之前看到的一些代码(但愿我现在能找到一个例子)是在严格模式下意图将其定义为未定义,不确定他们为什么要这样做。 - Mark Pieszak - Trilon.io
然而,如果您处于严格模式下,则即使进行简单的func()调用,this也不会引用全局对象。因此,即使在严格模式下,我也看不到使用没有this参数的func.call()的任何理由。 - Bart

0

是的,在某些情况下有重要的区别。例如,处理回调函数。假设您有一个带有构造函数的类,该构造函数接受callback参数并将其存储在this.callback下。稍后,当通过this.callback()调用此回调时,外部代码会通过this获得对您的对象的引用。这并不总是可取的,最好/更安全的方法是在这种情况下使用this.callback.call()

这样,外部代码将获取undefined作为this,并且不会意外地尝试修改您的对象。而正确编写的回调无论如何都不会受到call()的影响,因为它们会提供定义为箭头函数或通过.bind()绑定函数的回调。在这两种情况下,回调都将具有自己的适当的this,并且不受apply()/call()设置的值的影响,因为箭头和绑定函数只忽略这个值。


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