如何使用 JavaScript 来限制最小/最大值之间的数值?

我想在两个值之间限制一个数值,我知道在 PHP 中可以这样做:

$number = min(max(intval($number), 1), 20);
// this will make $number 1 if it's lower than 1, and 20 if it's higher than 20

我怎样才能在 javascript 中做到这一点,而不需要编写多个 if语句之类的东西。

122186 次浏览

Use Math.min and Math.max.

like this

var number = Math.min(Math.max(parseInt(number), 1), 20);

Live Demo:

function limitNumberWithinRange(num, min, max){
const MIN = min || 1;
const MAX = max || 20;
const parsed = parseInt(num)
return Math.min(Math.max(parsed, MIN), MAX)
}


alert(
limitNumberWithinRange(  prompt("enter a number")   )
)

You have at least two options:

You can use a pair of conditional operators (? :):

number = number > 100 ? 100 : number < 0 ? 0 : number;

Or you can combine Math.max and Math.min:

number = Math.min(100, Math.max(0, number));

In both cases, it's relatively easy to confuse yourself, so you might consider having a utility function if you do this in multiple places:

function clamp(val, min, max) {
return val > max ? max : val < min ? min : val;
}

Then:

number = clamp(number, 0, 100);

Use lodash's clamp method:

_.clamp(22, 1, 20) // Outputs 20

Needs no further explanation:

function clamp(value, min, max) {
return Math.min(Math.max(value, min), max);
}

Quote from this answer:

Update for ECMAScript 2017:

Math.clamp(x, lower, upper)

But note that as of today, it's a Stage 1 proposal. Until it gets widely supported, you can use a polyfill.

I will share my robust function to enforce whole numbers (because of the integer tag), it has features like optional min/max parameters and -0 protection:

function toInt(val, min, max){
val=(val*1 || 0);
val=(val<0 ? Math.ceil(val) : Math.floor(val));


min*=1;
max*=1;


min=((Number.isNaN(min) ? -Infinity : min) || 0);
max=((Number.isNaN(max) ? Infinity : max) || 0);


return Math.min(Math.max(val, min), max);
}

Some quick notes:

  • The (... || 0) behind the scenes is dealing with -0 to change it to 0, which is almost always what you want.
  • The min and max parameters are optional. When blank or invalid values are passed, they will turn into -Infinity and Infinity so they silently don't interfere with Math.min() and Math.max().
  • You can change Number.isNaN(x) ECMAScript-6 to x!==x (results in true only for NaN) for more compatibility with really old browsers, but this is simply not necessarily anymore.

You could easily just extend Math by adding your own method...

ES6

Math.minmax = (value, min, max) => Math.min(Math.max(value, min), max);

ES5

Math.minmax = function(value, min, max){
return Math.min(Math.max(value, min), max);
}

One Liners

const clamp = (num, min, max) => num > max ? max : num < min ? min : num
const minmax = (num, min, max) => Math.min(Math.max(num, min), max)

Benchmark

Browser clamp() minmax() Result
Chrome 976,066,844 ops/s 971,704,488 ops/s clamp() 0.45% faster
Firefox 872,108,437 ops/s 1,358,476,166 ops/s minmax() 35.8% faster
Edge 958,554,747 ops/s 936,113,887 ops/s clamp() 2.34% faster

JsBench https://jsbench.me/qhl99e1thl/1

In case of firefox minmax() is much faster in compare to others. Though in chrome and Edge clamp() is faster than minmax() but difference is ignorable. So, my opinion is to use minmax() according to the benchmark.