Javascript x.f.call(x,…)和x.f(…)之间有区别吗?

Javascript x.f.call(x,…)和x.f(…)之间有区别吗?,javascript,Javascript,我在看一些代码,看起来像 this.f.call(this); 或者在其他一些情况下 this.someObj.f.call(this.someObj); 这些和我的有什么区别吗 this.f(); this.someObj.f(); 是否存在行为不同的情况?(例如,如果this或someObj为空或实际上不是一个对象,或者f实际上不是一个函数,那么行为会有所不同吗?我想不出一种方法,其中一个会抛出异常,而另一个不会,但可能我遗漏了一些东西……) 编辑:澄清一下:是的,我知道.call可以

我在看一些代码,看起来像

this.f.call(this);
或者在其他一些情况下

this.someObj.f.call(this.someObj);
这些和我的有什么区别吗

this.f();
this.someObj.f();
是否存在行为不同的情况?(例如,如果
this
someObj
为空或实际上不是一个对象,或者
f
实际上不是一个函数,那么行为会有所不同吗?我想不出一种方法,其中一个会抛出异常,而另一个不会,但可能我遗漏了一些东西……)

编辑:澄清一下:是的,我知道
.call
可以用来指定函数看到的
这个
值,并且在不能使用
obj.f()
语法的情况下它会很有用(因为
f
不是
obj
的属性,或者您不知道它是否是)。我的问题不是关于
.call
通常是如何工作的。我的问题是关于这个案例,我看不出使用
.call
而不是对象属性语法的明显原因

两者之间没有区别。 如果我们检查语言规范,然后我们可以看到它们的行为完全相同

x.f.call(x)
执行以下操作:

返回调用func的[[Call]]内部方法的结果,提供thisArg作为this值,argList作为参数列表

在正常通话中:

返回对func调用[[Call]]内部方法的结果,提供thisValue作为this值,提供list argList作为参数值

其中,
具有分辨率(规范中11.2.3 7.b.i中规定)


所有现代JavaScript实现(是的,甚至IE8现代版)都尊重这一点。

是的,这些都会更改此值。即泛化方法,例如,您可以使用
.call
在DOM
节点列表上使用数组方法请详细说明。。。我知道
x.f.call(x)
会将函数中的
this
值设置为
x
,但是
x.f()
不会做完全相同的事情吗?你所说的“这些改变了<代码>这个值”是什么意思?我将编辑问题以澄清…所以不要传递<代码>这个进来,传递其他东西。例如
Array.prototype.forEach.call(document.querySelectorAll(“a”)、函数(link){console.log(link.href);}
将吐出页面中的所有链接,即使
querySelectorAll
-节点列表的返回值没有forEach方法。我编辑了这个问题来解释为什么它不是重复的。请取消标记。谢谢。@Intuite说它在一个插件中,他们正在努力实现跨浏览器兼容。我不知道为什么它是这样写的。我能想到的唯一一件事是,如果
Function.prototype.call
以某种方式被重新分配,可能会有所不同,但我确实希望他们没有这样做(这必须在某人的“如何使代码完全不可读”列表中)。他们大多数时候的行为都是一样的。可以执行
someMethod.toString=function(){return“Psych!”;},但您仍然可以使用
Function.prototype.toString.call(someMethod)获得原始代码。但是,如果原型本身被覆盖,它就不起作用。说句公道话,它与原来的问题(找出区别;))也略有不同。这不是我的意思,但那是我的错。我编辑了我的评论。@IngoBürk有趣的一点,但是-只有在您事先将对象的原始
保存到字符串
并在稍后将其应用到对象时,才会出现这种情况,我不知道如何在
x.f.call(x)中完成此操作
没有先将
x.f
保存到其他地方的场景。我的观点与问题的不同之处在于,它是
x.f()
x.prototype.f.call(x)
,而不是
x.f.call(x)
。我最近不得不使用它,因为库重写类构造函数的
toString
,但我可以使用
Function.prototype.toString
。示例(与我实际遇到的非常类似):