3

What might be the purpose of the following idiom?

Function.apply.call(fn, console, args);

I have never seen apply being "called" before.

Ben Aston
  • 45,997
  • 54
  • 176
  • 303

2 Answers2

4

To call a function, we need the 'function', 'this', and 'arguments'.

Using Function.apply or Function.call by themselves lets you specify 'this' and 'arguments' but not the function to call because they use their own this as the function, so we need an extra layer to set that 'this' value.

You could instead say:

fn.apply(console, args);

but this won't work if fn.apply has been overwritten.

fgb
  • 17,739
  • 2
  • 33
  • 50
2

It's certainly not idiomatic :-) Let's see what it does:

  • Function.apply is the Function.prototype.apply method - the Function constructor inherits it.
  • this method gets .called, with the fn as the this value, the console as the first argument, and args as the second.

So this should be equivalent to fn.apply(console, args), which invokes fn (probably a console method) on the console object with a dynamic args list.

So why is this done? Because Function.apply.call(fn, console, args) is not exactly equivalent to fn.apply(console, args)! It only is when fn.apply === Function.apply, which might not be the case.
It's unlikely that somebody would have overridden the .apply property - and if he did it was his fault -, but there is a real-world issue: fn objects that don't inherit from Function.prototype even though they are callable. Such can happen in buggy implementations of host objects; and the best-known example is Internet Explorer's console object.

Community
  • 1
  • 1
Bergi
  • 513,640
  • 108
  • 821
  • 1,164