10 JavaScript one-liners every developer should know

10 JavaScript one-liners every developer should know

Code should be readable and pragmatic. For me, that means I should quickly understand what a snippet does, which input it expects and where it stops being useful.

These are ten small JavaScript helpers I use or reach for when the problem fits. Each example includes input and expected output. A one-liner is useful when it makes an intention clear; I would expand it as soon as the short version hides important behavior.

1. Sleep/delay

I use a delay when simulating a slow response in a mock server. This helper returns a Promise that resolves after the timer runs, so I can pause an async function without blocking the JavaScript thread.

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
await sleep(200);
console.log("Mock response ready"); // Runs after the delay

The delay is a minimum, not an exact execution time. In an end-to-end test, I prefer waiting for an observable condition, such as a visible element or a completed request. A fixed sleep can make a test unnecessarily slow and still fail when the application takes longer.

2. Unique array values

A Set removes duplicate primitive values while preserving the order in which they first appear. Spreading it creates a new array.

const unique = values => [...new Set(values)];
unique(["Vue", "Angular", "Vue"]); // ["Vue", "Angular"]
unique([NaN, NaN]); // [NaN]

Objects are compared by reference, not by their properties. Two separate objects with the same id remain two entries. If uniqueness depends on an ID, compare that ID explicitly. See the Set documentation for its equality rules.

3. Random number between two values

This returns an integer between min and max, including both endpoints. I find it useful for sample data and simple simulations.

const random = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
random(1, 6); // An integer from 1 through 6
random(4, 4); // 4

This version expects a sensible integer range with min <= max. For repeatable tests, control the random source or use fixed input. Math.random() is not suitable for passwords, security tokens or other security-sensitive values.

4. Capitalize the first letter

For a simple label, I sometimes want to uppercase the first letter and leave the rest alone.

const capitalize = text => text.charAt(0).toUpperCase() + text.slice(1);
capitalize("javascript"); // "Javascript"
capitalize(""); // ""

This is a small string transformation, not a general name formatter. It works on UTF-16 code units, so it does not handle every Unicode character or locale-specific casing rule. For people's names, I prefer preserving the spelling they provide.

5. A variable with a default value

When a field may be missing, I usually want a fallback without replacing a valid zero, false or an empty string. That is where the nullish coalescing operator helps.

const value = input ?? defaultValue;
0 ?? 10; // 0
false ?? true; // false
"" ?? "Untitled"; // ""
null ?? "Untitled"; // "Untitled"
undefined ?? "Untitled"; // "Untitled"

|| uses the fallback for every falsy value: 0 || 10 becomes 10. That can be intentional, but it means something different. Choose based on the values your application accepts. MDN explains the difference between ?? and ||.

6. Detect even numbers

The remainder operator makes this straightforward for integers.

const isEven = number => number % 2 === 0;
isEven(8); // true
isEven(7); // false
isEven(-4); // true

I used this kind of check for alternating table rows years ago. For visual zebra striping, CSS :nth-child(even) is the more direct option. In JavaScript, keep this helper for values that have already been checked as integers; it is not input validation.

7. Turn a value into a boolean

Two logical NOT operators convert a value to its boolean truthiness. Boolean(value) is an equally valid, more explicit spelling.

const bool = !!value;
!!0; // false
!!""; // false
!!"false"; // true
!![]; // true

This does not parse the meaning of a value. The string "false" is non-empty and therefore truthy, as are empty arrays and objects. If data arrives as text, interpret the accepted values explicitly.

8. Debounce

A trailing debounce waits until calls have stopped for the specified delay, then invokes the callback with the latest arguments. Each wrapper needs its own timer. Storing that timer on the callback itself lets two wrappers around the same function cancel each other.

const debounce = (fn, delay) => { let timer; return function (...args) { clearTimeout(timer); timer = setTimeout(() => fn.apply(this, args), delay); }; };
const logSearch = debounce(query => console.log(query), 200);
logSearch("vu");
logSearch("vue");
// Logs only "vue" after the final delay.

This one is compact, but I would normally spread it over several lines. The timer stays inside the wrapper's closure, and the callback receives the this value from the latest call. This small version has no cancel, flush or maximum-wait option. For component cleanup or more advanced behavior, use a helper that provides those controls.

I explain the timing in more detail in the difference between debounce and throttle.

9. Truncate text with an ellipsis

When I need to shorten a string by length rather than by the available space on screen, this helper keeps the first length code units and adds an ellipsis.

const truncate = (text, length) => text.length > length ? text.slice(0, length) + "…" : text;
truncate("JavaScript", 4); // "Java…"
truncate("Vue", 4); // "Vue"

The limit should be a non-negative integer and does not include the added ellipsis. This version can split emoji or other multi-unit characters, and it does not preserve whole words. For layout-dependent truncation, CSS is often a better fit.

10. Compare array values

Two arrays with the same entries are still different objects. A strict equality check compares the array references; this helper instead compares their lengths and values in order.

const equal = (a, b) => a.length === b.length && Array.from(a).every((value, index) => value === b[index]);
equal([1, 2], [1, 2]); // true
equal([1, 2], [2, 1]); // false
equal([{ id: 1 }], [{ id: 1 }]); // false
equal([, 2], [1, 2]); // false

This is a shallow comparison using ===. Nested objects still have to be the same references, and NaN does not equal itself. Array.from() turns empty slots into undefined, so they are compared instead of being skipped. It treats an empty slot and an explicit undefined as equivalent. Calling every() directly on a sparse array would skip those slots.

Comments

There are no comments yet, leave yours below.

Leave a comment

Do you have an addition, question or experience related to this article? Share it below.

Comments are briefly reviewed before they appear.

Read more about:

The bullshit of code coverage

A test suite can reach 100% coverage and still charge the wrong shipping fee or take a payment twice. Through boundary cases, misleading mocks and missing requirements, I examine what coverage actually proves. The useful question is not whether the code ran, but whether the tests would catch the mistakes your customers care about.

Continue reading

The difference between debounce and throttle

Debounce waits for a pause; throttle limits how often work can run while events keep arriving. That difference matters for search fields, scrolling and other frequent interactions. This article explains both techniques with practical use cases, helping you choose the behaviour your interface needs rather than treating them as interchangeable performance tricks.

Continue reading

The bullshit of frontend development

The bullshit of frontend development

Frontend tooling was supposed to help us deliver. So why do straightforward websites turn into months of work? Drawing on my experience, I challenge unnecessary frameworks, custom abstractions and premature optimisation, and ask where accessibility and our users went in the process.

Continue reading