Home Programming Mastering JavaScript Functional Programming - Third Edition

Mastering JavaScript Functional Programming - Third Edition

By Federico Kereki
books-svg-icon Book
Subscription FREE
eBook + Subscription $15.99
eBook $39.99
Print + eBook $49.99
READ FOR FREE Free Trial for 7 days. $15.99 p/m after trial. Cancel Anytime! BUY NOW BUY NOW BUY NOW
What do you get with a Packt Subscription?
This book & 7000+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook + Subscription?
Download this book in EPUB and PDF formats
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook?
Download this book in EPUB and PDF formats
Access this title in our online reader
DRM FREE - Read whenever, wherever and however you want
Online reader with customised display settings for better reading experience
What do you get with video?
Download this video in MP4 format
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with Audiobook?
Download a zip folder consisting of audio files (in MP3 Format) along with supplementary PDF
READ FOR FREE Free Trial for 7 days. $15.99 p/m after trial. Cancel Anytime! BUY NOW BUY NOW BUY NOW
Subscription FREE
eBook + Subscription $15.99
eBook $39.99
Print + eBook $49.99
What do you get with a Packt Subscription?
This book & 7000+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook + Subscription?
Download this book in EPUB and PDF formats
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook?
Download this book in EPUB and PDF formats
Access this title in our online reader
DRM FREE - Read whenever, wherever and however you want
Online reader with customised display settings for better reading experience
What do you get with video?
Download this video in MP4 format
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with Audiobook?
Download a zip folder consisting of audio files (in MP3 Format) along with supplementary PDF
  1. Free Chapter
    Chapter 2: Thinking Functionally – A First Example
About this book
Functional programming is a programming paradigm that uses functions for developing software. This book is filled with examples that enable you to leverage the latest JavaScript and TypeScript versions to produce modern and clean code, as well as teach you to how apply functional programming techniques to develop more efficient algorithms, write more concise code, and simplify unit testing. This book provides comprehensive coverage of the major topics in functional programming to produce shorter, clearer, and testable programs. You’ll begin by getting to grips with writing and testing pure functions, reducing side effects, as well as other key features to make your applications functional in nature. The book specifically explores techniques to simplify coding, apply recursion, perform high-level coding, learn ways to achieve immutability, implement design patterns, and work with data types. By the end of this book, you’ll have developed the practical programming skills needed to confidently enhance your applications by adding functional programming to wherever it’s most suitable.
Publication date:
April 2023
Publisher
Packt
Pages
614
ISBN
9781804610138

 

Thinking Functionally – A First Example

In Chapter 1, Becoming Functional, we went over what FP is, mentioned some advantages of applying it, and listed some tools we’d need in JavaScript. For now, let’s leave the theory behind and start by considering a simple problem and how to solve it in a functional way.

In this chapter, we will do the following:

  • Look at a simple, e-commerce-related problem
  • Consider several usual ways to solve it (with their associated defects)
  • Find a way to solve the problem by looking at it functionally
  • Devise a higher-order solution that can be applied to other problems
  • Work out how to carry out unit testing for functional solutions

In future chapters, we’ll be returning to some of the topics listed here, so we won’t be going into too much detail. We’ll just show how FP can give a different outlook on our problem and leave further details for later.

After working through this chapter, you will have had a first look at a common problem and at a way of solving it by thinking functionally, as a prelude for the rest of this book.

 

Our problem – doing something only once

Let’s consider a simple but common situation. You have developed an e-commerce site; the user can fill their shopping cart, and in the end, they must click on a Bill me button so that their credit card will be charged. However, the user shouldn’t click twice (or more), or they will be billed several times.

The HTML part of your application might have something like this somewhere:

<button id="billButton"
    onclick="billTheUser(some, sales, data)">Bill me
      </button>

And, among the scripts, you’d have something similar to the following code:

function billTheUser(some, sales, data) {
  window.alert("Billing the user...");
  // actually bill the user
}

A bad example

Assigning the events handler directly in HTML, the way I did it, isn’t recommended. Instead, unobtrusively, you should set the handler through code. So, do as I say, not as I do!

This is a bare-bones explanation of the web page problem, but it’s enough for our purposes. Now, let’s get to thinking about ways of avoiding repeated clicks on that button. How can we manage to prevent the user from clicking more than once? That’s an interesting problem, with several possible solutions – let’s start by looking at bad ones!

How many ways can you think of to solve our problem? Let’s go over several solutions and analyze their quality.

Solution 1 – hoping for the best!

How can we solve the problem? The first solution may seem like a joke: do nothing, tell the user not to click twice, and hope for the best! Your page might look like Figure 2.1:

Figure 2.1 – An actual screenshot of a page, just warning you against clicking more than once

Figure 2.1 – An actual screenshot of a page, just warning you against clicking more than once

This is a way to weasel out of the problem; I’ve seen several websites that just warn the user about the risks of clicking more than once and do nothing to prevent the situation. So, the user got billed twice? We warned them... it’s their fault!

Your solution might simply look like the following code:

<button
  id="billButton"
  onclick="billTheUser(some, sales, data)">Bill me
</button>
<b>WARNING: PRESS ONLY ONCE, DO NOT PRESS AGAIN!!</b>

Okay, this isn’t an actual solution; let’s move on to more serious proposals.

Solution 2 – using a global flag

The solution most people would probably think of first is using some global variable to record whether the user has already clicked on the button. You define a flag named something like clicked, initialized with false. When the user clicks on the button, if clicked is false, you change it to true and execute the function; otherwise, you do nothing at all. This can be seen in the following code:

let clicked = false;
.
.
.
function billTheUser(some, sales, data) {
  if (!clicked) {
    clicked = true;
    window.alert("Billing the user...");
    // actually bill the user
  }
}

This works, but it has several problems that must be addressed:

  • You are using a global variable, and you could change its value by accident. Global variables aren’t a good idea, in JavaScript or other languages. You must also remember to re-initialize it to false when the user starts buying again. If you don’t, the user won’t be able to make a second purchase because paying will become impossible.
  • You will have difficulties testing this code because it depends on external things (that is, the clicked variable).

So, this isn’t a very good solution. Let’s keep thinking!

Solution 3 – removing the handler

We may go for a lateral kind of solution, and instead of having the function avoid repeated clicks, we might just remove the possibility of clicking altogether. The following code does just that; the first thing that billTheUser() does is remove the onclick handler from the button, so no further calls will be possible:

function billTheUser(some, sales, data) {
  document
    .getElementById("billButton")
    .onclick = null;
  window.alert("Billing the user...");
  // actually bill the user
}

This solution also has some problems:

  • The code is tightly coupled to the button, so you won’t be able to reuse it elsewhere
  • You must remember to reset the handler; otherwise, the user won’t be able to make a second purchase
  • Testing will also be more complex because you’ll have to provide some DOM elements

We can enhance this solution a bit and avoid coupling the function to the button by providing the latter’s ID as an extra argument in the call. (This idea can also be applied to some of the further solutions that we’ll see.) The HTML part would be as follows; note the extra argument to billTheUser():

<button
  id="billButton"
  onclick="billTheUser('billButton', some, sales, data)"
>Bill me
</button>

We also have to change the called function so that it will use the received buttonId value to access the corresponding button:

function billTheUser(buttonId, some, sales, data) {
  document.getElementById(buttonId).onclick = null;
  window.alert("Billing the user...");
  // actually bill the user
}

This solution is somewhat better. But, in essence, we are still using a global element – not a variable, but the onclick value. So, despite the enhancement, this isn’t a very good solution either. Let’s move on.

Solution 4 – changing the handler

A variant to the previous solution would be not to remove the click function, but to assign a new one instead. We are using functions as first-class objects here when we assign the alreadyBilled() function to the click event. The function warning the user that they have already clicked could look something like this:

function alreadyBilled() {
  window.alert("Your billing process is running; don't
    click, please.");
}

Our billTheUser() function would then be like the following code – note how instead of assigning null to the onclick handler as in the previous section, now, the alreadyBilled() function is assigned:

function billTheUser(some, sales, data) {
  document
    .getElementById("billButton")
    .onclick = alreadyBilled;
  window.alert("Billing the user...");
  // actually bill the user
}

There’s a good point to this solution; if the user clicks a second time, they’ll get a warning not to do that, but they won’t be billed again. (From the point of view of user experience, it’s better.) However, this solution still has the very same objections as the previous one (code coupled to the button, needing to reset the handler, and harder testing), so we don’t consider it quite good anyway.

Solution 5 – disabling the button

A similar idea here is instead of removing the event handler, we can disable the button so the user won’t be able to click. You might have a function such as the one shown in the following code, which does exactly that by setting the disabled attribute of the button:

function billTheUser(some, sales, data) {
  document
    .getElementById("billButton")
    .setAttribute("disabled", "true");
  window.alert("Billing the user...");
  // actually bill the user
}

This also works, but we still have objections as with the previous solutions (coupling the code to the button, needing to re-enable the button, and harder testing), so we don’t like this solution either.

Solution 6 – redefining the handler

Another idea: instead of changing anything in the button, let’s have the event handler change itself. The trick is in the second line of the following code; by assigning a new value to the billTheUser variable, we are dynamically changing what the function does! The first time you call the function, it will do its thing, but it will also change itself out of existence by giving its name to a new function:

function billTheUser(some, sales, data) {
  billTheUser = function() {};
  window.alert("Billing the user...");
  // actually bill the user
}

There’s a special trick in the solution. Functions are global, so the billTheUser=... line changes the function’s inner workings. From that point on, billTheUser will be the new (null) function. This solution is still hard to test. Even worse, how would you restore the functionality of billTheUser, setting it back to its original objective?

Solution 7 – using a local flag

We can go back to the idea of using a flag, but instead of making it global (which was our main objection to the second solution), we can use an Immediately Invoked Function Expression (IIFE), which we’ll see more about in Chapter 3, Starting Out with Functions, and Chapter 11, Implementing Design Patterns. With this, we can use a closure, so clicked will be local to the function and not visible anywhere else:

var billTheUser = (clicked => {
  return (some, sales, data) => {
    if (!clicked) {
      clicked = true;
      window.alert("Billing the user...");
      // actually bill the user
    }
  };
})(false);

This solution is along the lines of the global variable solution, but using a private, local variable is an enhancement. (Note how clicked gets its initial value from the call at the end.) The only drawback we could find is that we'll have to rework every function that needs to be called only once to work in this fashion (and, as we’ll see in the following section, our FP solution is similar to it in some ways). Okay, it’s not too hard to do, but don’t forget the Don’t Repeat Yourself (DRY), usual advice!

We have now gone through multiple ways of solving our “do something only once” problem – but as we’ve seen, they were not very good! Let’s think about the problem functionally so that we get a more general solution.

 

A functional solution to our problem

Let’s try to be more general; after all, requiring that some function or other be executed only once isn’t that outlandish, and may be required elsewhere! Let’s lay down some principles:

  • The original function (the one that may be called only once) should do whatever it is expected to do and nothing else
  • We don’t want to modify the original function in any way
  • We need a new function that will call the original one only once
  • We want a general solution that we can apply to any number of original functions

A SOLID base

The first principle listed previously is the single responsibility principle (the S in the SOLID acronym), which states that every function should be responsible for a single functionality. For more on SOLID, check the article by Uncle Bob (Robert C. Martin, who wrote the five principles) at butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod.

Can we do it? Yes, and we’ll write a higher-order function, which we’ll be able to apply to any function, to produce a new function that will work only once. Let’s see how! We will introduce higher-order functions in Chapter 6, Producing Functions. There, we’ll go about testing our functional solution, as well as making some enhancements to it.

A higher-order solution

If we don’t want to modify the original function, we can create a higher-order function, which we’ll (inspiredly!) name once(). This function will receive a function as a parameter and return a new function, which will work only once. (As we mentioned previously, we’ll be seeing more of higher-order functions later; in particular, see the Doing things once, revisited section of Chapter 6, Producing Functions).

Many solutions

Underscore and Lodash already have a similar function, invoked as _.once(). Ramda also provides R.once(), and most FP libraries include similar functionality, so you wouldn’t have to program it on your own.

Our once() function may seem imposing at first, but as you get accustomed to working in an FP fashion, you’ll get used to this sort of code and find it to be quite understable:

// once.ts
const once = <FNType extends (...args: any[]) => any>(
  fn: FNType
) => {
  let done = false;
  return ((...args: Parameters<FNType>) => {
    if (!done) {
      done = true;
      return fn(...args);
    }
  }) as FNType;
};

Let’s go over some of the finer points of this function:

  • Our once() function receives a function (fn) as its parameter and returns a new function, of the same type. (We’ll discuss this typing in more detail shortly.)
  • We define an internal, private done variable, by taking advantage of closure, as in Solution 7. We opted not to call it clicked (as we did previously) because you don’t necessarily need to click on a button to call the function; we went for a more general term. Each time you apply once() to some function, a new, distinct done variable will be created and will be accessible only from the returned function.
  • The return statement shows that once() will return a function, with the same type of parameters as the original fn() one. We are using the spread syntax we saw in Chapter 1, Becoming Functional. With older versions of JavaScript, you’d have to work with the arguments object; see developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/arguments for more on that. The modern way is simpler and shorter!
  • We assign done = true before calling fn(), just in case that function throws an exception. Of course, if you don’t want to disable the function unless it has successfully ended, you could move the assignment below the fn() call. (See Question 2.4 in the Questions section for another take on this.)
  • After the setting is done, we finally call the original function. Note the use of the spread operator to pass along whatever parameters the original fn() had.

Typing for once() may be obscure. We have to specify that the type of the input function and the type of once() are the same, and that’s the reason for defining FNType. Figure 2.2 shows that TypeScript correctly understands this (Check the answer to Question 1.7 at the end of this book for another example of this):

Figure 2.2 – Hovering shows that the type of once()’s output matches the type of its input

Figure 2.2 – Hovering shows that the type of once()’s output matches the type of its input

If you’re not still used to TypeScript, let’s see the pure JavaScript equivalent, which is the same code but for typing:

// once_JS.js
const once = (fn) => {
  let done = false;
  return (...args) => {
    if (!done) {
      done = true;
      return fn(...args);
    }
  };
};

So, how would we use it? We first create a new version of the billing function.

const billOnce = once(billTheUser);

Then, we rewrite the onclick method as follows:

<button id="billButton"
  onclick="billOnce(some, sales, data)">Bill me
</button>;

When the user clicks on the button, the function that gets called with the (some, sales, data) argument isn’t the original billTheUser() but rather the result of having applied once() to it. The result of that is a function that can be called only a single time.

You can’t always get what you want!

Note that our once() function uses functions such as first-class objects, arrow functions, closures, and the spread operator. Back in Chapter 1, Becoming Functional, we said we’d be needing those, so we’re keeping our word! All we are missing from that chapter is recursion, but as the Rolling Stones sang, You Can’t Always Get What You Want!

We now have a functional way of getting a function to do its thing only once, but how would we test it? Let’s get into that topic now.

Testing the solution manually

We can run a simple test. Let’s write a squeak() function that will, appropriately, squeak when called! The code is simple:

// once.manual.ts
const squeak = a => console.log(a, " squeak!!");
squeak("original"); // "original squeak!!"
squeak("original"); // "original squeak!!"
squeak("original"); // "original squeak!!"

If we apply once() to it, we get a new function that will squeak only once. See the highlighted line in the following code:

// continued...
const squeakOnce = once(squeak);
squeakOnce("only once"); // "only once squeak!!" squeakOnce("only once"); // no output
squeakOnce("only once"); // no output

The previous steps showed us how we could test our once() function by hand, but our method is not exactly ideal. In the next section, we’ll see why and how to do better.

Testing the solution automatically

Running tests by hand isn’t suitable: it gets tiresome and boring, and it leads, after a while, to not running the tests any longer. Let’s do better and write some automatic tests with Jest:

// once.test.ts
import once } from "./once";
describe("once", () => {
  it("without 'once', a function always runs", () => {
    const myFn = jest.fn();
    myFn();
    myFn();
    myFn();
    expect(myFn).toHaveBeenCalledTimes(3);
  });
  it("with 'once', a function runs one time", () => {
    const myFn = jest.fn();
    const onceFn = jest.fn(once(myFn));
    onceFn();
    onceFn();
    onceFn();
    expect(onceFn).toHaveBeenCalledTimes(3);
    expect(myFn).toHaveBeenCalledTimes(1);
  });
});

There are several points to note here:

  • To spy on a function (for instance, to count how many times it was called), we need to pass it as an argument to jest.fn(); we can apply tests to the result, which works exactly like the original function, but can be spied on.
  • When you spy on a function, Jest intercepts your calls and registers that the function was called, with which arguments, and how many times it was called.
  • The first test only checks that if we call the function several times, it gets called that number of times. This is trivial, but we’d be doing something wrong if that didn’t happen!
  • In the second test, we apply once() to a (dummy) myFn() function, and we call the result (onceFn()) several times. We then check that myFn() was called only once, though onceFn() was called three times.

We can see the results in Figure 2.3:

Figure 2.3 – Running automatic tests on our function with Jest

Figure 2.3 – Running automatic tests on our function with Jest

With that, we have seen not only how to test our functional solution by hand but also in an automatic way, so we are done with testing. Let’s just finish by considering an even better solution, also achieved in a functional way.

Producing an even better solution

In one of the previous solutions, we mentioned that it would be a good idea to do something every time after the first click, and not silently ignore the user’s clicks. We’ll write a new higher-order function that takes a second parameter – a function to be called every time from the second call onward. Our new function will be called onceAndAfter() and can be written as follows:

// onceAndAfter.ts
const onceAndAfter = <
  FNType extends (...args: any[]) => any
>(
  f: FNType,
  g: FNType
) => {
  let done = false;
  return ((...args: Parameters<FNType>) => {
    if (!done) {
      done = true;
      return f(...args);
    } else {
      return g(...args);
    }
  }) as FNType;
};

We have ventured further into higher-order functions; onceAndAfter() takes two functions as parameters and produces a third one, which includes the other two within.

Function as default

You could make onceAndAfter() more powerful by giving a default value for g, such as () => {}, so if you didn’t specify the second function, it would still work fine because the default do-nothing function would be called instead of causing an error.

We can do a quick-and-dirty test along the same lines as we did earlier. Let’s add a creak() creaking function to our previous squeak() one and check out what happens if we apply onceAndAfter() to them. We can then get a makeSound() function that should squeak once and creak afterward:

// onceAndAfter.manual.ts
import { onceAndAfter } from "./onceAndAfter";
const squeak = (x: string) => console.log(x, "squeak!!");
const creak = (x: string) => console.log(x, "creak!!");
const makeSound = onceAndAfter(squeak, creak);
makeSound("door"); // "door squeak!!"
makeSound("door"); // "door creak!!"
makeSound("door"); // "door creak!!"
makeSound("door"); // "door creak!!"

Writing a test for this new function isn’t hard, only a bit longer. We have to check which function was called and how many times:

// onceAndAfter.test.ts
import { onceAndAfter } from "./onceAndAfter";
describe("onceAndAfter", () => {
  it("calls the 1st function once & the 2nd after", () => {
    const func1 = jest.fn();
    const func2 = jest.fn();
    const testFn = jest.fn(onceAndAfter(func1, func2));
    testFn();
    testFn();
    testFn();
    testFn();
    expect(testFn).toHaveBeenCalledTimes(4);
    expect(func1).toHaveBeenCalledTimes(1);
    expect(func2).toHaveBeenCalledTimes(3);
  });
});

Notice that we always check that func1() is called only once. Similarly, we check func2(); the count of calls starts at zero (the time that func1() is called), and from then on, it goes up by one on each call.

 

Summary

In this chapter, we’ve seen a common, simple problem based on a real-life situation. After analyzing several typical ways of solving that, we went for a functional thinking solution. We saw how to apply FP to our problem and found a more general higher-order solution that we could apply to similar problems with no further code changes. We saw how to write unit tests for our code to round out the development job.

Finally, we produced an even better solution (from the point of view of the user experience) and saw how to code it and how to unit-test it. Now, you’ve started to get a grip on how to solve a problem functionally; next, in Chapter 3, Starting Out with Functions, we’ll delve more deeply into functions, which are at the core of all FP.

 

Questions

2.1 No extra variables: Our functional implementation required using an extra variable, done, to mark whether the function had already been called. Not that it matters, but could you make do without using any extra variables? Note that we aren’t telling you not to use any variables, it’s just a matter of not adding any new ones, such as done, and only as an exercise!

2.2 Alternating functions: In the spirit of our onceAndAfter() function, can you write an alternator() higher-order function that gets two functions as arguments and, on each call, alternatively calls one and another? The expected behavior should be as in the following example:

const sayA = () => console.log("A");
const sayB = () => console.log("B");
const alt = alternator(sayA, sayB);
alt(); // A
alt(); // B
alt(); // A
alt(); // B
alt(); // A
alt(); // B

2.3 Everything has a limit! As an extension of once(), could you write a higher-order function, thisManyTimes(fn,n), that would let you call the fn() function up to n times, but would do nothing afterward? To give an example, once(fn) and thisManyTimes(fn,1) would produce functions that behave the same way. Do also write tests for it.

2.4 Allow for crashing: Suppose we apply once() to a function, and the first time that function gets called, it crashes. Here, we may want to allow a second call to the function, hoping it wouldn’t crash again. We want an onceIfSuccess() function, that will get a function as a parameter and produce a new function that will run successfully only once, but will be allowed to fail (throwing exceptions) many times if need be. Implement onceIfSuccess(), and don’t forget to write unit tests for it.

2.5 Say no to arrows: Implement once() using classic functions, instead of arrow functions. This is just meant to help you explore the slightly different needed data typing syntax.

About the Author
  • Federico Kereki

    Federico Kereki is a Uruguayan Systems Engineer, with a Master's degree in Education, and over 30 years of experience as a consultant, system developer, and writer. Currently a Subject Matter Expert at Globant, he has taught at Universidad de la República, Universidad ORT Uruguay, and Universidad de la Empresa. He has written articles and booklets on programming, web development, security, and open source topics for blogs, magazines, and websites. He has also written several books, including Modern JavaScript Web Development Cookbook and the upcoming Data Structures and Algorithms in JavaScript. He resides, works, and teaches in Uruguay, but he wrote the first edition of this book while working in India, and the second edition during a sojourn in Mexico.

    Browse publications by this author
Mastering JavaScript Functional Programming - Third Edition
Unlock this book and the full library FREE for 7 days
Start now