让我给你举个例子。
function a() { console.log(1) }
function b() { console.log(2) }
a.call(b) // 1
a.call.call(b) // 2
a.call.call.call(b) // 2
为什么?
我们知道a.call(b)
表示使用参数b
调用a()
函数。
因此,a.call.call(b)
表示使用参数b
调用Function.prototype.call()
函数,与Function.prototype.call.call(b)
相同。
但是Function.prototype.call.call()
不是普通的函数对象。 它可以被调用,但它没有属性。 有一些独特的规则来调用它。
Function.prototype.call.call(a) // 1
Function.prototype.call.call(b) // 2
事实上,Function.prototype.call.call(b)
是一个异国情调对象,进一步说是一个绑定函数异国情调对象。
[规范] 绑定函数是包装另一个函数对象的异国情调对象。
[规范] 调用绑定函数通常会导致调用其封装的函数。
因此,Function.prototype.call.call(a)
简单地意味着 a()
。
a.call.call(x)
意味着调用 x,也就是 x()
。
Function.prototype.call(thisArg)
中,如果 thisArg 为 undefined 或 null,则将其替换为全局对象。a.call.call()
意味着 a.call.call(undefined)
意味着 a.call.call(window)
意味着调用 window
。
试图调用 window
,你会得到 Uncaught TypeError: window is not a function
,所以试图调用 a.call.call()
,你会得到 Uncaught TypeError:a.call.call 不是函数
。
希望这可以帮助。
.call
?它是在 Function.prototype
内可用的函数。
因此,它可以在任何函数上调用,这正是您能够调用 a.call
的原因。.call
做什么?它在您调用 .call
的函数上设置 this
上下文。因此,在您的情况下,当您调用 a.call
时,它可以在函数 a
上设置一个 this
上下文(通过您传递给 .call
函数的第一个参数)。
.call
函数内部的 this
是什么?它就是您调用 .call
的函数(在您的情况下是 a
),
因此,为了简单起见,您可以假设在 .call
中调用函数如 this()
(即调用 a()
)- 到目前为止都很好。a.call.call
.call
(我从左往右数)调用了第一个.call
并为第一个.call
设置了this
,这只是第一个参数,也就是一个函数。.call
将调用this()
(请记住,这是由第二个.call
设置的,并且它是您传递的第一个参数,这是一个函数)。a.call.call
感到困惑。这是因为你在想我的函数a
在所有这些混乱中去哪了?
实际上,在你调用第二个.call
时,this
传递给第一个.call
来自第二个.call
,这使得你的函数a
在这种情况下变得不必要。Function.prototype.call.call(...)
Object.call.call(...)
上周我对这些事情感到困惑(不是.call.call
而是.call.bind
),我在这里提出了一个问题,有人非常详细地解释了这个问题,你可以在这里找到。
我试着从我提出的问题的理解来回答。
毕竟这就是SO的用途
更新:
你的问题是:“似乎b.call(与a.call.call相同)正在调用第一个参数,即函数,然后将第二个参数作为this传递。如果第一个参数不是函数,则抛出“不是函数”的错误。”
你的假设在这里是正确的
call
函数的工作原理,并给出了一些示例。我在这里确切地询问的是call.call
,它的行为与call
不同。而且我无法理解call.call
的工作原理。 - tjfdfs.call()
的第一个参数是你想要在call()
执行的函数中设置为this
值的对象。如果call()
本身就是要操作的函数,因为你已经链接了.call.call()
,那么它会如何处理提供的this
值呢?它会假设它是一个函数并尝试调用它。但是你的最后一行代码没有传递一个函数,而是传递了一个空对象。 - nnnnnnb
和a
没有任何关系:a
只是设置b
引用call
函数的机制的一部分。 - nnnnnn