← Download MyJS
MyJS block
clamp 1.0.0
Limits a value to a range: `min` if it's below the range, `max` if it's above it, and the value itself otherwise.
- Exports
-
clamp - Works in
- Browser and Node.js
The code of version 1.0.0
/**
* Limits a value to a range: `min` if it's below the range, `max` if it's
* above it, and the value itself otherwise.
*
* For numbers it works like the proposed `Math.clamp()`: `NaN` for any `NaN`
* argument, and `-0` and `+0` are kept apart (`clamp(-0, 0, 10)` is `+0`).
* Unlike the proposal, it also works on anything `<` and `>` can compare:
* BigInts, strings (alphabetically), Dates, and BigInts mixed with numbers.
* When the value is outside the range, the bound itself is returned (the same
* Date object, for example).
*
* A bound that's `undefined` (or `-Infinity`/`Infinity` for numbers) means no
* limit on that side. `null` isn't a missing bound: it counts as 0. When both
* bounds are strings they're compared alphabetically, so numbers in strings
* don't work as expected (`clamp(5, '9', '10')` throws, because `'9'` comes
* after `'10'`).
*
* @param {number|bigint|string|Date|*} value
* The value to limit.
* @param {number|bigint|string|Date|*} [min]
* The lowest value allowed, or `undefined` for no lower limit.
* @param {number|bigint|string|Date|*} [max]
* The highest value allowed, or `undefined` for no upper limit.
* @returns {number|bigint|string|Date|*}
* `min` if `value` is below it, `max` if `value` is above it, otherwise
* `value` (or `NaN` if any of them are `NaN` numbers).
* @throws {RangeError}
* If `min` is greater than `max` (including `min` being `+0` and `max` `-0`).
*
* @example
* clamp(15, 0, 10); // 10
* clamp(-5, 0, 10); // 0
* clamp(5, 0, 10); // 5
* clamp(5, 0, Infinity); // 5
* clamp(NaN, 0, 10); // NaN
* clamp(-0, 0, 10); // 0 (+0)
*
* @example
* clamp(15n, 0n, 10n); // 10n
* clamp('m', 'a', 'f'); // 'f'
* clamp(150, undefined, 100); // 100 (no lower limit)
*
* @example
* // Keeps a date within this year
* const start = new Date(2026, 0, 1);
* const end = new Date(2026, 11, 31);
* clamp(new Date(2031, 5, 1), start, end) === end; // true
*
* @example
* clamp(5, 10, 0); // throws a RangeError
*/
function clamp(value, min, max) {
// min > max misses +0 and -0, which are equal to <, so they're checked by sign
if (min > max || (min === 0 && max === 0 && 1 / min > 1 / max)) {
throw new RangeError('The min must be less than or equal to max.');
}
return (typeof value === 'number' && typeof min === 'number' && typeof max === 'number')
? Math.max(min, Math.min(value, max))
: value < min
? min
: value > max
? max
: value;
}
Versions
-
1.0.0 Oct 16, 2026
Initial