how can i use Function.prototype.call instead of apply?

395 views Asked by At

I'm trying to use a 'Function.prototype.call'instead of an 'Function.prototype.apply' for use in ie8.

function testLog(){
  console.log.apply(console, arguments) // not supported 'apply' ie8
}
testLog(1,2,3) // 1,2,3

'Function.prototype.apply' is not supported in ie8,

function testLog(){
  // console.log.call(console, ...arguments)  //not supported 'spread operator' ie8

  console.log.call(console, Array.prototype.slice.call(arguments));
}
testLog(1,2,3) // [1,2,3]  

I tried to use 'Function.prototype.call', but I'm having trouble because ie can't support spread operator .

How can I get 1,2,3 instead of [1,2,3] using 'Function.prototype.call'?


additional explanation

I didn't find console.log not supported in ie8.

but, console.log is written as an example. I hope the focus should be on 'apply' and 'call'

Also, currently running on ie8, 'call' is enabled and 'apply' is still not available.

[apply] https://caniuse.com/?search=ES%205.1%3A%20generic%20array-like%20object%20as%20arguments

[call] https://caniuse.com/?search=JavaScript%20built-in%3A%20Function%3A%20call

1

There are 1 answers

1
Sebastian Simon On BEST ANSWER

As T.J. Crowder was able to test and confirm in his answer (now deleted) and comments, console.log in Internet Explorer 8 doesn’t have the (full) Function prototype.

I’ve just verified that although IE8 supports Function.prototype.apply and call on JavaScript functions, it doesn’t support either of them on console.log. (console is host-provided. Host-provided functions don’t have to be full JavaScript functions, and they were very weird in older versions of IE.)

T.J. Crowder, 2021-08-23 08:43:41 UTC

This means that calling .apply directly on console.log, doesn’t work. It is, nonetheless, a function, so it should behave as one, even if it doesn’t expose the methods you expect it to have.

In order to get the desired result you’d expect to get with the expression

console.log.apply(console, arguments);

you can call apply on console.log indirectly, using Function.prototype.call:

Function.prototype.apply.call(console.log, console, arguments);

This calls the method apply with the context console.log and provides console and arguments as arguments, which looks just like console.log.apply(console, arguments).

This also works in modern browsers and, of course, it works with any function that takes an arbitrary amount of arguments, e.g. Math.max: Function.prototype.apply.call(Math.max, Math, arguments).

Note that the “array” in apply must either be a proper Array or an arguments object, not any generic array-like object (like { 0: 4, 1: 2, length: 2 }). That is because, as MDN confirms, IE8 doesn’t support a generic array-like object as an arguments. Appendix E of ECMAScript 5.1 is a bit more specific: in IE8, only Arrays and arguments objects are allowed as the second argument of apply.