2

When I try

[1,2,3].forEach(alert);

it opens message box for every item of the array as expected.

But when I try

[1,2,3].forEach(console.log);

I receive following error

Uncaught TypeError: Illegal invocation

Why?

Jan Turoň
  • 31,451
  • 23
  • 125
  • 169
  • Is this issue specific to Google Chrome? – Tchoupi May 17 '13 at 18:37
  • `[1,2,3].forEach(console.log)` works fine in Firefox. – nullability May 17 '13 at 18:38
  • @MathieuImbert I know that in IE `console.log` returns error itself unless debug console is on. I suspect it is not an ordinary function, but I'm not sure. Maybe each browser implement it different way? – Jan Turoň May 17 '13 at 18:40
  • For what it's worth, you can always do `console.log(1, 2, 3);` to see three separate elements. That may not fit your use case, though. – ErikE May 17 '13 at 18:42

2 Answers2

7

Personally I get Invalid calling object.

See, [1,2,3].forEach(console.log) is essentially a shorthand way of iterating over the array and for each item running console.log.call(theArray,theItem). However, console.log requires that this be an object of type Console, thus the error.

Try [1,2,3].forEach(function(i) {console.log(i);})

Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
  • 2
    Excellent! I managed to solve it by passing the console into its context as you explained and it works: `[1,2,3].forEach(console.log.bind(console));` Could you please add it into your answer to help others running into this question? – Jan Turoň May 17 '13 at 18:41
1

Actually, it doesn't work in Firefox, or at least not as you might expect:

[1,2,3].forEach(console.log)

Gives you:

1 0 [1, 2, 3]
2 1 [1, 2, 3]
3 2 [1, 2, 3]

Why? MDN has your answer:

callback is invoked with three arguments:

  • the element value

  • the element index

  • the array being traversed

However,

[1,2,3].forEach(function(i) { console.log(i); });

Works exactly as you'd expect in both Firefox and Chrome.

Matt Burland
  • 44,552
  • 18
  • 99
  • 171
  • I know - it is just odd to create anonymous function just to call native function. Thanks for useful explanation anyway. – Jan Turoň May 17 '13 at 18:48
  • @JanTuroň: Well the problem is the way JavaScript is dynamically typed, so you can call functions with any number of arguments (or none at all) of any type and it will *try* and do something. Sometimes it'll give you an error, sometimes it'll do something unexpected. – Matt Burland May 17 '13 at 18:53