a 是一个函数,那么 `a.call.call` 到底做了什么?

a is a function, then what `a.call.call` really do?

这些代码在 chrome devtool 上 运行。

似乎 b.call(与 a.call.call 相同)调用第一个参数,它是一个函数,然后将第二个参数作为 this 传递。 如果第一个参数不是函数,则抛出 not a function 错误。

谁能解释一下 <Function>.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 过时这种情况 )

在你的情况下 .call.call 应该在 Function.prototypeObject 或任何其他函数上被调用(记住 .callFunction.prototype 的一部分并且可以被任何函数调用)

所以你应该已经完成​​了

Function.prototype.call.call(...)

甚至

Object.call.call(...)

现在我上周对这些事情很困惑(不是.call.call而是.call.bind),我在这里问了一个问题,有人给我解释得很详细,你可以找到它

我试着根据我对我问的问题的理解来回答。

毕竟这就是 SO 的目的

更新:

你的问题"It seems like b.call(same as a.call.call) is calling the first argument, which is a function, then pass the second argument as this. If the first argument is not a function, then throw not a function error."

你的假设是正确的

举个例子。

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) 表示使用 thisb.

调用 a()

因此 a.call.call(b) 意味着调用 Function.prototype.call()this 值 b,与 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)是一个Exotic Object,而且是一个Bound Function Exotic Object。

  • [说明] 绑定函数是包装另一个函数对象的奇异对象。

  • [说明] 调用绑定函数通常会调用其包装函数。

所以 Function.prototype.call.call(a) 就是 a().

a.call.call(x)表示调用x,即x().

  • [规范]在Function.prototype.call(thisArg)中,如果thisArg未定义或为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 is not a function.

希望对您有所帮助。