These codes are run on chrome devtool.
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.
Can someone explain how <Function>.call.call
work?
Let me show you an example.
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
Why?
We know a.call(b)
means invoke a()
with this value b
.
So that a.call.call(b)
means invoke Function.prototype.call()
with this value b, same as Function.prototype.call.call(b)
.
But Function.prototype.call.call()
is not an ordinary function Object. It can be invoked but it has no property. There's some unique rules to invoke it.
Function.prototype.call.call(a) // 1
Function.prototype.call.call(b) // 2
In fact, Function.prototype.call.call(b)
is an Exotic Object, furthermore, a Bound Function Exotic Object.
[Specification] A bound function is an exotic object that wraps another function object.
[Specification] Calling a bound function generally results in a call of its wrapped function.
So that Function.prototype.call.call(a)
simply means a()
.
a.call.call(x)
means invoke x, that is, x()
.
Function.prototype.call(thisArg)
, if thisArg is undefined or null, it will be replaced by global object.a.call.call()
means a.call.call(undefined)
means a.call.call(window)
means invoke window
.
Try to invoke window
you'll get Uncaught TypeError: window is not a function
, so try to invoke a.call.call()
you'll get Uncaught TypeError: a.call.call is not a function
.
Hope it helps.