1

I was trying to solve https://twitter.com/secoif/status/730207047892017153 when I got an error message I don't understand. I get the error when running this code

const fns = [
  function () {
    console.log(1)
  },
  function () {
    console.log(2)
  },
  function () {
    console.log(3)
  }
]

fns.map(Function.prototype.call.bind)

Chrome tells me "Bind must be called on a function", which I don't understand. The following line, which should be equivalent, does not throw the same error.

fns.map((x) => Function.prototype.call.bind(x))
xuanji
  • 5,007
  • 2
  • 26
  • 35
  • 1
    Related [How to pass the method defined on prototype to Array.map as callback](http://stackoverflow.com/questions/33006222/how-to-pass-the-method-defined-on-prototype-to-array-map-as-callback) – Tushar May 19 '16 at 15:44
  • @Tushar interesting, but if the reason is that map passes two arguments, I can't see why `fns.map((x, y) => Function.prototype.call.bind(x, y))` would work – xuanji May 19 '16 at 15:47
  • 1
    `bind` is not bound to `call`. You'd want to do `fns.map(Function.prototype.bind, Function.prototype.call)` instead (or `fns.map(Function.prototype.bind.bind(Function.prototype.call))` if you prefer that) – Bergi May 19 '16 at 15:48

2 Answers2

0

To solve the JS pop quiz, you can do this:

for (var x in fns) fns[x]();

However, I realize that's not what you're asking :).

There are a few things I don't understand in your approach:

1) Why are you using .map()? Map is used for returning another array, which is not needed, so why not forEach() instead?

2) I'm not sure why you are using bind. When using map(), the callback is passed 3 parameters: the current function, the index of the function in the array, and the array itself. When you look at the syntax for bind(), you'll notice the first param for bind is the 'this' object, followed by the parameters to be passed in the function being bound to. In this case, 'this' will be set to the current function, index and array will be passed as parameters to the function.

3) Using bind on call. call() will take the same parameters a bind(), where the first one is the 'this' and the rest are parameters to be passed into the function being called. When you used .bind(), it will set the 'this' object as function and the first param will be the index. So from the perspective of .call(), you're setting it's 'this' to the function, and passing the index as the first param to call(), which is call's 'this', which then passes the whole array as the first parameter to the function.

Long story short, you're getting your values all mixed up and your overcomplicating this.

Rob Brander
  • 3,702
  • 1
  • 20
  • 33
0

from the docs mdn docs for map

thisArg Optional. Value to use as this when executing callback. Default value is the Window object

As marked before, you can map:

fns.map(Function.prototype.call.bind, Function.prototype.call.bind)

If you call:

fns.map(Function.prototype.call.bind)

Bind apply on object not function! and error raised, because object has not bind method.

VelikiiNehochuha
  • 3,775
  • 2
  • 15
  • 32