For a brief period of time, say, about 3–4 years ago, if you wanted to sound really smart, you’d bring up “functional programming”. Name-dropping LISP or even better, Haskell during an interview marked you as a cut above the hoi polloi. Even I, surly and too smart for this, fell into the trap of calling JavaScript “LISP with curly braces”, just because it had closures.
Still, functional programming features have percolated through other languages because they work. They’re another tool for the job, and like any tool, when used by the inexpert, someone might lose a finger. Or perhaps someone should lose a finger, if only as a warning to others.
For example, what if you wanted to execute a loop 100 times in JavaScript? You could use a crummy old for
loop, but that’s not functional. The functional solution comes from an anonymous submitter:
Array.apply(null, {length: 99}).map(Number.call, Number).forEach(function (element, index) {
// do some more crazy stuff
});
This is actually an amazing abuse of JavaScript’s faculties, and I thought I saw the worst depredations one could visit on JavaScript while working with Angular code. When I first read this line, my initial reaction was, “oh, that’s not so bad.” Then I tried to trace through its logic. Then I realized, no, this is actually really bad. Not just extraneous arrays bad, but full abused of JavaScript bad. Like call Language Protective Services bad. This is easier to explain if you look at it backwards.
forEach
applies a function to each element in the array, supplying the element and the index of that element.
Number.call
invokes the Number
function, used to convert things into numbers (shocking, I know), but it allows you to supply the this
against which the function is executed. map
takes a callback function, and supplies an array item for the currentValue
, the index
, and the whole array
as parameters. map
also allows you to specify what this
is, for the callback itself- which they set to be Number
- the function they’re calling.
So, remember, map
expects a callback in the form f(currentValue, index, array)
. We’re supplying a function: call(thisValue, numberToConvert)
. So, the end result of map
in this function is that we’re going to emit an array with each element equal to its own index, which makes the forEach
look a bit silly.
Finally, at the front, we call Array.apply
, which is mostly the same as Array.call
, with a difference in how arguments get passed. This allows the developer to deftly avoid writing new Array(99)
, which would have the same result, but would look offensively object-oriented.