Search code examples
javascriptcall

why call.call invokes function


Here if I have a function which logs "called my function"

function myFunction() {
  console.log('called my function')
}

Function.prototype.call.call(myFunction) // => "called my function"

while during a single call like:

function myFunction() {
  console.log('called my function')
}
Function.prototype.call(myFunction)


Solution

  • When you write someFunction.call(foo), it means to call someFunction while passing foo as the this parameter. Normally you have someObject.someFunction(), which passes someObject as this implicitly, but with .call you can set this to anything you want. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call.

    So what does Function.prototype.call(myFunction) do? Well, it calls Function.prototype, passing myFunction as this. What does calling Function.prototype do? According to the ECMA specification:

    The Function prototype object is itself a Function object (its [[Class]] is "Function") that, when invoked, accepts any arguments and returns undefined.

    That's why Function.prototype.call(myFunction) has no visible effect.

    On the other hand, Function.prototype.call.call(myFunction) calls Function.prototype.call (which is itself a function!), passing myFunction as this. What does this do? Exactly the same as myFunction.call(): When you look up the call property of a function object, you get it from Function.prototype anyway (through object inheritance). So what does this do? It calls myFunction with no (normal) arguments, but the value of this it sees is a bit tricky: If the function is in strict mode, this will be undefined; if it is non-strict, this will be the global object (a.k.a. window in browsers).

    This is also the same behavior you get from myFunction() (i.e. not calling it on an object). In other words, Function.prototype.call.call(foo) is just a (very) roundabout way of writing foo().