假设我正在开发一个导出 clamp()
函数的 JavaScript 库,
它将数字限制在给定范围内。
export function clamp(n, min, max) {
return Math.min(Math.max(n, min), max);
}
但是如果 min
大于 max
,则此函数将失败。有两种解决方案
这看起来很明智。
首先,该函数可能返回 NaN
:
export function clamp(n, min, max) {
return min <= max ? Math.min(Math.max(n, min), max) : NaN;
}
其次,该函数可能会抛出异常:
export function clamp(n, min, max) {
if (min > max) {
throw new RangeError('min may not be greater than max');
}
return Math.min(Math.max(n, min), max);
}
在这种情况下,哪种解决方案最好?
我会尝试回答我自己的问题,但我肯定会接受更好的 一个。
最佳答案
这里需要考虑三个问题:如果用户期望一些输入怎么办 无效?如果无效输入是无意的怎么办?以及什么模式 在该语言中常见吗?
当预期输入无效时
用户可能认为某些输入无效。如果函数返回NaN
,这些情况很容易处理。
let values = [[2, 4, 6], [3, 5, 1], [7, 5, 9]];
let clamped = values.map(args => clamp(...args)).filter(n => !isNaN(n));
console.log(clamped); // [4, 7]
如果函数抛出异常,用户将不得不使用
try...catch
statement ,这会更冗长且性能更低。或者她
可以在应用clamp()
之前过滤掉无效输入,但随后她
必须确切地知道哪些类型的输入无效,哪些可能是
比本例中的情况更复杂。
这显然是支持 NaN
选项的一点。
当意外输入无效时
如果函数能够更容易地调试部分用户的真正错误 抛出异常。例如,用户很容易犯这样的错误: 这个:
clamp(-4, 0, -10);
如果上面返回 NaN
,调试可能会是一场噩梦,尤其是在
一个庞大的代码库,还有很多其他事情正在发生。如果该函数是
抛出异常,用户会看到:
RangeError: min may not be greater than max
at clamp ...
简单得多。这显然是 throw
的胜利。
常见语言模式
所以我们打平了。我们最好的选择是问自己,WWJD(JavaScript 会怎样?
做)?例如,当我们将负数传递给 Math.sqrt()
时会发生什么?
console.log(Math.sqrt(-4)); // NaN
它返回NaN
。这是决胜局。 JavaScript 程序员会期望
如果输入无效,此类函数将返回 NaN。他们会
习惯于处理源自此行为的错误,或者如果没有,
那么他们最好习惯它。
因此返回NaN
。
关于javascript - 我的 JavaScript API 应该在无效输入时抛出或返回值吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38163537/