Basic Utility Functions
-
debounce
Optimize PerformanceThis prevents a function from executing too frequently (e.g. for search inputs, resize events). Debounce function is crucial for performance optimization because it helps reduce the number of function executions, expecially for events that fire frequently, such as:
- Window resize
- Scrolling
- Typing (e.g., search input)
- Mouse movement
How Debounce Works
Debounce delays the execution of a function until a specified delay has passed since the last time the function was called. Creating this functions for your system is very important.
Example:
function debounce(func, delay) { let timer; return function (...args) { clearTimeout(timer); timer = setTimeout(() => func.apply(this, args), delay); }; }
-
throttle
Limit function callsEnsures a function is executed at most once in a given interval. The
throttle
function is essential for performance optimization because it ensures a function execute at most once within a given time interval, even if it's triggered multiple times.It's useful for high-frequency events, such as:
- Scrolling (e.g., infinite scrolling, lazy loading)
- Window resizing
- Mouse movement (e.g., tracking cursor position)
- Button clicks (e.g., preventing double submission)
How Throttle Works
Throttle limits the number of times a function executes per unit of time. Unlike debounce, which executes until activity stops, throttle ensures regular execution intervals regardless of how frequently the event fires.
Example:
function throttle(func, limit) { let lastFunc; let lastRan; return function (...args) { if (!lastRan) { func.apply(this, args); lastRan = Date.now(); } else { clearTimeout(lastFunc); lastFunc = setTimeout(() => { if (Date.now() - lastRan >= limit) { func.apply(this, args); lastRan = Date.now(); } }, limit - (Date.now() - lastRan)); } }; }
Array and Object Manipulation
In JavaScript, objects and arrays are reference types, meaning they are stored in memory as references. When you assign an object/array top a new variable, both variables point to the same memory location, leading to unintended side effects if one is modified.
✅ Cloning helps prevent accidental modifications
✅ Ensures data integrity when working with functions
✅ Useful for immutability (e.g., in React state management)
-
Clone an Object or Array (Shallow Copy)
const clone = (obj) => ({ ...obj }); const arrClone = (arr) => [...arr];
-
Deep Clone an Object
function deepClone(obj) { return JSON.parse(JSON.stringify(obj)); }
-
Remove Duplicates from an Array
const removeDuplicates = (arr) => [...new Set(arr)];
-
Flatten a Nested Array
const flatten = (arr) => arr.flat(Infinity);
String Manipulation
-
Capitalize First Letter
const capitalize = (str) => str.charAt(0).toUpperCase() + str.slice(1);
-
Convert a String to Slug (URL=Friendly)
This is commonly used for blogs, news, etc. or viewing users. Instead of using the id of a user or blog or news. Use a slog instead. Especially in blog or news, having slug on the URL is a lot better because its SEO friendly and enhances readability of the URL.
const toSlug = (str) => str.toLowerCase().replace(/\s+/g, '-').replace(/[^\w-]/g, '');
Dom Manipulation
-
Select Elements
const $ = (selector) => document.querySelector(selector); const $$ = (selector) => document.querySelectorAll(selector);
The following two functions are shorthand utilities for selecting elements in the DOM. They are shorter alternatives to writing
document.querySelecter()
anddocument.querySelectorAll()
, making code more concise and readable.The
$
function is equivalent todocument.querySelector()
, which returns the first matching element for the given CSS selector.
const title = $("h1"); // Selects the first <h1> element console.log(title.textContent);
Same as:
const title = document.querySelector("h1");
-
Toggle Class
const toggleClass = (el, className) => el.classList.toggle(className);
This function toggles (adds or remove) a CSS class from an element when called. It checks if the class exists:
- ✅ If the class is present, it removes it.
- ✅ if the class is absent, it adds it.
Example:
const btn = document.querySelector("#themeToggle"); btn.addEventListener("click", () => { toggleClass(document.body, "dark-mode"); });
The CSS Example:
.dark-mode { background: black; color: white; }
-
Copy Text to Clipboard
Copying text to the clipboard is essential for improving user experience in web applications. It allows users to quickly copy links, codes, or text without manually selecting and right-clicking. This function is widely used in share buttons, code snippets, form inputs, and password managers. Knowing how to implement it ensures better accessibility, efficiency, and smoother interactions in modern web development. 🚀
const copyToClipboard = (text) => navigator.clipboard.writeText(text);
Event Handling
-
Detect Click Outside an Element
This function detects clicks outside a specific element and triggers a callback function.
✅ Prevents unintended interactions✅ Useful for closing dropdowns, modals, or sidebars✅ Enhances user experience
function clickOutside(element, callback) { document.addEventListener('click', (event) => { if (!element.contains(event.target)) callback(); }); }
Example:
// closing the modal if clicked outside a modal const modal = document.querySelector("#modal"); const closeModal = () => modal.classList.remove("open"); clickOutside(modal, closeModal);
-
Smooth Scroll to Element
const smoothScroll = (element) => { document.querySelector(element).scrollIntoView({ behavior: 'smooth' }); };
This function smoothly scrolls to a specific element on the page when called.
How It Works:
-
document.querySelector(element)
– Finds the DOM element based on the provided CSS selector. -
scrollIntoView({ behavior: 'smooth' })
– Scrolls to the selected element with a smooth animation instead of an abrupt jump.
-
Date & Time
-
Format Date as
YYYY-MM-DD
A lot of people does not know this, but you can use this one line code to get date in
YYYY-MM-DD
format.
const formatDate = (date) => date.toISOString().split('T')[0];
This function formats a JavaScript
Date
object into a YYYY-MM-DD format (ISO 8601), which is commonly used for displaying dates in a consistent format.Example:
const today = new Date(); console.log(formatDate(today)); // Output: "2025-02-02"
-
Get Time Ago (e.g., "5 minutes ago")
This function returns a human-readable "time ago" string based on a given date, for example: "2 days ago", "5 hours ago", or "just now". It's useful for displaying relative timestamps on posts, comments, or activity logs.
function timeAgo(date) { const seconds = Math.floor((new Date() - date) / 1000); const intervals = { year: 31536000, month: 2592000, day: 86400, hour: 3600, minute: 60 }; for (const [unit, value] of Object.entries(intervals)) { const count = Math.floor(seconds / value); if (count >= 1) return `${count} ${unit}${count > 1 ? 's' : ''} ago`; } return 'just now'; }
How It Works:
-
new Date() - date
– Calculates the difference between the current time and the givendate
. - Divides the difference by 1000 – Converts the difference into seconds.
-
intervals
Object – Maps time units (year, month, day, etc.) to their equivalent value in seconds. - Loop through intervals – Determines which unit (year, month, day, etc.) best fits the difference in time and returns the corresponding string (e.g., "5 minutes ago").
-
Fallback – If the time difference is very short (less than a minute), it returns "just now".
Example:
const postDate = new Date("2025-01-30T12:00:00"); console.log(timeAgo(postDate)); // Output: "3 days ago"
-
Fetch & Async/Await
-
Fetch Data with Error Handling
This function performs an HTTP request to a given
url
and returns the response as JSON. It is a simple and effective alternative to Axios for making network requests, especially when you don't need the overhead of a library.
async function fetchData(url) { try { const response = await fetch(url); if (!response.ok) throw new Error('Network error'); return await response.json(); } catch (error) { console.error(error); } }
Why Is This Function Great Without Using Axios?
-
Native to JavaScript –
fetch
is built into modern browsers, so you don't need to include any external dependencies (like Axios). It works out-of-the-box in most environments, including browsers and Node.js (vianode-fetch
). -
Async/Await Syntax – It uses
async/await
to handle asynchronous requests in a more readable and synchronous-like manner, making it easier to manage promises compared to.then()
or.catch()
. -
Error Handling – The function throws an error when the response is not
ok
(status code outside 200-299), providing a basic mechanism to catch network errors easily. It also catches any other errors using thetry-catch
block. -
Smaller Footprint – Since
fetch
is a built-in browser API, there’s no need to import or install any additional libraries, making this solution lighter and faster to use compared to adding the weight of Axios (which is great but may be unnecessary for simple use cases).
🎯 When Should You Consider Using fetch
Over Axios?
-
Simple Use Cases – If you don't need all the extra features that Axios offers (like request/response interceptors, automatic JSON parsing, etc.),
fetch
is perfect for making basic GET or POST requests. -
No Need for Extra Libraries – If you want to avoid adding dependencies to your project,
fetch
is an ideal choice since it’s natively supported in most modern browsers. -
Lightweight Projects – For small projects or cases where you only need simple API calls,
fetch
is fast and sufficient without the extra weight of a third-party library.
Example:
const url = "https://jsonplaceholder.typicode.com/posts";
fetchData(url).then((data) => {
console.log(data);
});
Functional Programming Helpers
-
Memoization (Cache Expensive Function Calls)
function memoize(fn) { const cache = new Map(); return function (...args) { const key = JSON.stringify(args); if (!cache.has(key)) cache.set(key, fn(...args)); return cache.get(key); }; }
The
memoize
function is a performance optimization technique that stores (or "caches") the results of function calls and returns the cached result when the same inputs are encountered again, rather than recalculating the result. This is especially useful for expensive or repetitive calculations.
How It Works:
cache = new Map()
– A map to store results of previously executed function calls. The keys are the stringified arguments, and the values are the corresponding function results.key = JSON.stringify(args)
– Converts the function arguments into a JSON string to use as a cache key.if (!cache.has(key))
– Checks if the result for this set of arguments already exists in the cache.cache.set(key, fn(...args))
– If the result isn't in the cache, it calls the function and stores the result in the cache.-
return cache.get(key)
– If the result exists in the cache, it simply returns the cached result.Example Usage:
- Memoizing a Factorial Function
function factorial(n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
const memoizedFactorial = memoize(factorial);
console.log(memoizedFactorial(5)); // Calculates and caches result
console.log(memoizedFactorial(5)); // Returns cached result
✅ The first call will calculate the result and cache it, while subsequent calls with the same argument will return the cached result.
2. Memoizing Expensive Computations
function slowComputation(num) {
console.log('Calculating...');
return num * num; // Simulate expensive computation
}
const memoizedComputation = memoize(slowComputation);
console.log(memoizedComputation(10)); // Will calculate
console.log(memoizedComputation(10)); // Will return cached result
✅ The second call to memoizedComputation(10)
will not log "Calculating..." since it returns the cached value.
Memoization is a technique that stores function results and returns cached results when the same inputs are used again. This is useful for expensive computations, improving performance, and reducing redundant calculations.
-
Generate a Random String
const randomString = (length = 8) => Math.random().toString(36).substr(2, length);
This function generates a random alphanumeric string of a specified length (default is 8 characters).
Example:
console.log(randomString()); // Example output: "y8d4sj2g" console.log(randomString(12)); // Example output: "4df7y9qs2zxg"
🎯 Why Use
randomString
?- Quick Random Value – Great for generating short random strings in a single line of code.
- Use Cases – Often used for generating unique IDs, tokens, or passwords in scenarios like form submissions, URL shorteners, or session identifiers.
- Customization – The function allows you to easily adjust the string length by passing a custom argument.
These might not be functions you use every day, but knowing them can really come in handy for future projects or even ones you're working on right now.
I hope this was helpful! Thanks for reading, and have an awesome day—happy coding! 😁🍻
If you enjoy this article and would like to show your support, you can easily do so by buying me a coffee. Your contribution is greatly appreciated!
Top comments (2)
For deep cloning an object, you're probably better off using the built-in JS function
structuredClone
.I have always underestimate the use of java script. Thanks for uploading this post. Have some value-able piece of information!