10 Helpful JavaScript Utility Functions
Tags: javascript, productivity, community, discuss
Published: 2023-03-04 13:13:50

Hey, there! 👋

Today, we'll cover 10 custom utility functions in JavaScript that can come in handy in most of your projects.

## Table of Contents

- [01. `console.log()`](#01-consolelog)
- [02. `querySelector()`](#02-queryselector)
- [03. `addEventListener()`](#03-addeventlistener)
- [04. `random()`](#04-random)
- [05. `times()`](#05-times)
- [06. `slugify()`](#06-slugify)
- [07. `validateEmail()`](#07-validateemail)
- [08. `capitalize()`](#08-capitalize)
- [09. `sanitizeHTML()`](#09-sanitizehtml)
- [10. `localStorage()`](#10-localstorage)
- [Resources](#resources)
- [Conclusion](#conclusion)

---

<h2 id="01-consolelog">01. `console.log()`</h2>

Yes, the tool we all love and use for printing, debugging, etc. So, why not shorten it to reduce typing and save some time?

```js
const { log } = console;

log("Hello world!");
// Expected output: Hello world!

// SAME AS //

console.log("Hello world!");
// Expected output: Hello world!
```

Explanation: we use the [destructuring assignment](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) to be able to extract the `log` method from the `console`.

---

<h2 id="02-queryselector">02. `querySelector()`</h2>

When working with JavaScript, you might have heard the term [DOM Manipulation](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Manipulating_documents) and used `getElementById()`, `querySelector()` and other methods to access the DOM elements. So, let's make it _easier_ to work with.

```js
const select = (selector, scope = document) => {
  return scope.querySelector(selector);
};

const title = select("h1");
const className = select(".class");
const message = select("#message", formElem);

// SAME AS //

const title = document.querySelector("h1");
const className = document.querySelector(".class");
const message = formElem.querySelector("#message");
```

Explanation: We're passing 2 parameters in the `select()` function:

- 1st: [DOM](https://developer.mozilla.org/en-US/docs/Glossary/DOM) element you want to select
- 2nd: Scope from which you access that element (default = `document`);

---

<h2 id="03-addeventlistener">03. `addEventListener()`</h2>

Handling the click, mousemove and other events are mostly implemented with the [`addEventListener()`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener) method.

```js
const listen = (target, event, callback, ...options) => {
  return target.addEventListener(event, callback, ...options);
};

listen(buttonElem, "click", () => console.log("Clicked!"));

listen(document, "mouseover", () => console.log("Mouse over!"));

listen(formElem, "submit", () => {
    console.log("Form submitted!");
  }, { once: true }
);
```

Explanation: We're passing 4 parameters in the `listen()` function:

- 1st: Element you want to target (e.g. 'window', 'document' or specific DOM element)
- 2nd: Event type (e.g. 'click', 'submit', 'DOMContentLoaded', etc.)
- 3rd: Callback function
- 4th: Remaining optional [options](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#parameters) (e.g. 'capture', 'once', etc.). Also, we use the [spread syntax] (...) to allow for other options if necessary. Otherwise, it can be omitted just like in the `addEventListener` method.

---

<h2 id="04-random">04. `random()`</h2>

You might probably be aware of `Math.random()` function that generates random numbers from 0 to 1. You might also know about other hacks, like `Math.random() * 10`, which should now generate random numbers from 0 to 10. However, the problem is that despite knowing the limit, we don't have much control over the minimum value.

```js
const random = (min, max) => {
  return Math.floor(Math.random() * (max - min + 1)) + min;
};

random(5, 10);
// 7
```

Explanation: Here's the better explanation by [MDN Docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random)

---

<h2 id="05-times">05. `times()`</h2>

Sometimes, we often find ourselves in need of running a particular function several times.

Of course, we can use [`setInterval()`](https://developer.mozilla.org/en-US/docs/Web/API/setInterval) to run every interval amount of time like this:

```js
setInterval(() => {
  randomFunction();
}, 5000); // runs every 5 seconds
```

The problem is that we aren't able to specify how many times we want to run it. So, let's fix it!

```js
const times = (func, n) => {
  Array.from(Array(n)).forEach(() => {
    func();
  });
};

times(() => {
  randomFunction();
}, 3); // runs 3 times
```

Explanation:

- [`Array(n)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Array) - creates a new array with the length of `n`.

```js
Array(5); // => [,,]
```

- [`Array.from()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from) - creates a shallow copy from `Array(n)`. It helps us to make an array to be usable, filling it with 'undefined'. You can also use the [`Array.prototype.fill()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill) method to achieve the same result.

```js
Array.from(Array(3)); // => [undefined,undefined,undefined]
```

> **Note:** While researching this utility function, I realized that some programmers prefer to put the `n` parameter first and then the function `times(n, func)`. But, it looked kinda weird to me, so I decided to swap their places, thus making the syntax more similar to the `setInterval()` function:

```js
setInterval(func, delay);

times(func, n);
```

Also, you call it `setTimes()` instead of `times()` to match with the `setInterval()` and `setTimeout()` methods depending on your preferences.

---

<h2 id="06-slugify">06. `slugify()`</h2>

Have you ever found yourself in need of turning the title of your blog articles into a 'URL-like' format?

```
JS Utility Functions => js-utility-functions
```

Here is a little utility function that does so:

```js
const slugify = (string, separator = "-") => {
  return string
    .toString() // Cast to string (optional)
    .toLowerCase() // Convert the string to lowercase letters
    .trim() // Remove whitespace from both sides of a string (optional)
    .replace(/\s+/g, separator) // Replace spaces with -
    .replace(/[^\w\-]+/g, "") // Remove all non-word chars
    .replace(/\_/g, separator) // Replace _ with -
    .replace(/\-\-+/g, separator) // Replace multiple - with single -
    .replace(/\-$/g, ""); // Remove trailing -
};

slugify("Hello, World!");
// Expected output: "hello-world"

slugify("Hello, Universe!", "_");
// Expected output: "hello_universe"
```

Explanation: Here is the discussion by the [GitHub community](https://gist.github.com/codeguy/6684588)

---

<h2 id="07-validateemail">07. `validateEmail()`</h2>

When working on small projects and trying out email validation for your form, you can use this _super simple_ method to achieve your goal. Also, it can be very handy for small tests.

```js
const validateEmail = (email) => {
  const regex = /^\S+@\S+\.\S+$/;
  return regex.test(email);
};

validateEmail("youremail@org.com"); // true
validateEmail("youremail@com"); // false
validateEmail("youremail.org@com"); // false
```

Explanation: You can play around with the regex [here](regexr.com/79hio).

- [`RegExp.test()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test) searches if the provided regex expression matches with the string

> **Note:** For larger projects, I would recommend using libraries like [validator.js](https://www.npmjs.com/package/validator) to handle heavy lifting for you.

---

<h2 id="08-capitalize">08. `capitalize()`</h2>

We have built-in `toUpperCase()` and `toLowerCase()` methods in JavaScript. However, we don't have built-in support for capitalization. So, let's build one!

```js
const capitalize = (str) => {
  const arr = str.trim().toLowerCase().split(" ");

  for (let i = 0; i < arr.length; i++) {
    arr[i] = arr[i].charAt(0).toUpperCase() + arr[i].slice(1);
  }

  return arr.join(" ");
};

capitalize("hello, world!");
// Expected output: "Hello, World!"
```

Explanation:

- [`split()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split) - turns the string into an array
- `arr[i].charAt(0).toUpperCase()` - upper cases the 1st letter of each word
- `arr[i].slice(1)` - returns the remaining word letters.
- `arr.join(" ")` - turns the array back into string

---

<h2 id="09-sanitizehtml">09. `sanitizeHTML()`</h2>

Ever heard of [Cross-site scripting (XSS) attacks](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting)? If not, it's a type of attack that occurs on most websites. For example, when submitting a form, an attacker might try to send malicious scripts to break into the system. To prevent this from happening on your forms, you can use this handy function that will "sanitize" the script code.

```js
const sanitizeHTML = (str) => {
  const div = document.createElement("div");
  div.textContent = str;
  return div.innerHTML;
};

sanitizeHTML("<h1>Hello, World!</h1>");
// Expected output: "&lt;h1&gt;Hello, World!&lt;/h1&gt;"
```

Explanation: Unlike `innerHTML`, `textContent` does not parse the string as HTML, while `innerText` only shows "human-readable" elements.

> Moreover, using `textContent` can prevent XSS attacks. - [MDN Docs](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent#differences_from_innerhtml)

![Sanitized HTML use case in real-life](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/31d5llsbw6rru33i0d2v.png)

---

<h2 id="10-localstorage">10. `localStorage`</h2>
## 

You might have used `localStorage` in your to-do list applications or any other projects to save the particular data in the user's computer memory. When getting and setting items, you have to use JSON `parse()` and `stringify()` methods to achieve the desired result. So, let's make it easier to work with them.

```js
const storage = {
  get: (key, defaultValue = null) => {
    const value = localStorage.getItem(key);
    return value ? JSON.parse(value) : defaultValue;
  },
  set: (key, value) => localStorage.setItem(key, JSON.stringify(value)),
  remove: (key) => localStorage.removeItem(key),
  clear: () => localStorage.clear(),
};

storage.set("motto", "Eat, Sleep, Code, Repeat");
storage.get("motto");
```

Explanation: If you aren't aware of JSON `parse()` and `stringify()` methods, check out the [MDN Docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON) for a better explanation.

Note: It was quite tough for me to come up with a good name that would make much more sense than just `storage`. Because at first glance, developers might not know whether it's referring to the 'localStorage' or something else. However, you can name it whatever you want. Also, if you've found any good names, please do let me know in the comments section.

---

## Resources

- [MDN Docs](https://developer.mozilla.org/en-US/)
- [10 JavaScript Functions - YouTube](https://youtu.be/LDgPTw6tePk)
- [JS Utility Functions - Web Dev Simplified](https://www.youtube.com/watch?v=EoUIS2PxKCs)
- many more... 😅

## Conclusion

If you've any questions or suggestions, the comment section is all yours. We might make part 2 of this article with your suggestions.

Thanks for reading! 🙂

[🔝 Back to Top](#table-of-contents)