Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Not So Easy Functional Programming in JavaScript

DZone 's Guide to

Not So Easy Functional Programming in JavaScript

In this quick tutorial, we go over how to implement the fundamentals of functional programming in our JavaScript code.

· Web Dev Zone ·
Free Resource

Introduction

JavaScript allows for operating on arrays in a functional way, e.g. using filter or map functions. As an argument for these functions, we can pass lambda expressions or function references. Is there a difference between them? The answer is yes.

What's the Problem?

In our project, we are building a mapping using the String.fromCharCode function. To simplify the usage of this function, my code looked similar to:

[66, 67, 68].map(v => String.fromCharCode(v))

When we run this code with the node we received [ 'B', 'C', 'D' ], but when we decided to refactor it to use a function reference the result was different:

> [66, 67, 68].map(String.fromCharCode)
[ 'B\u0000\u0000', 'C\u0001\u0000', 'D\u0002\u0000' ]

What Happened?

To find the reason for this behavior, let's first play with the function String.fromCharCode alone:

> String.fromCharCode(66)
'B'
> String.fromCharCode([66, 67, 68])
'\u0000'
> String.fromCharCode(66, 67, 68)
'BCD'

String.fromCharCode deals with various types and numbers of arguments.

Now, let's examine the function map:

> [66, 67, 68].map(v => v)
[ 66, 67, 68 ]
> [66, 67, 68].map((v, u) => [v, u])
[ [ 66, 0 ], [ 67, 1 ], [ 68, 2 ] ]
> [66, 67, 68].map((v, u, w) => [v, u, w])
[ [ 66, 0, [ 66, 67, 68 ] ],
  [ 67, 1, [ 66, 67, 68 ] ],
  [ 68, 2, [ 66, 67, 68 ] ] ]

map, like many other array functions, passes always three arguments to the function. The first is thecurrent value, the second is the index of the current value, and the third is the whole array.

It means that passing String.fromCharCode to the map function under the hood looks like this:

> [66, 67, 68].map((v, u, w) => String.fromCharCode(v, u, w))
[ 'B\u0000\u0000', 'C\u0001\u0000', 'D\u0002\u0000' ]

And this is equal to the initial example.

Conclusion

We have to be careful when we want to use a function which can take more than one argument, but we want to pass only the value. We have to pass the function as a lambda expression:

> [66, 67, 68].map(v => String.fromCharCode(v))
[ 'B', 'C', 'D' ]

or create another function which ensures that only the first argument will be passed to the desired function:

> const useOnlyValue = f => v => f(v);
undefined
> [66, 67, 68].map(useOnlyValue(String.fromCharCode))
[ 'B', 'C', 'D' ]
Topics:
javascript ,web dev ,javascript tutorials ,functional programming

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}