我的JavaScript API应该抛出或返回无效输入的值吗?

时间:2016-07-02 19:02:50

标签: javascript error-handling

假设我正在开发一个导出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);
}

在这种情况下,哪种解决方案最好?

我将尝试回答我自己的问题,但我肯定会接受更好的问题 之一。

1 个答案:

答案 0 :(得分:1)

此处需要考虑三个问题:如果用户需要一些输入,该怎么办? 无效?如果无效输入是无意的,该怎么办?什么样的模式 通常在语言中找到?

当预期无效输入时

用户可能希望某些输入无效。如果函数返回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]

如果函数抛出异常,则用户必须使用a 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