在JavaScript中打破NaN

是否有任何现代浏览器会引起NaN传播异常(即,对NaN乘以或加一个数字),或者可以对其进行配置?

静默的NaN传播是错误的可怕且阴险的来源,我希望能够及早发现它们,即使性能受到影响。


这是use strictjshint等的示例错误。 不会接:

object = new MyObject();
object.position.x = 0;
object.position.y = 10;

// ... lots of code

var newPosition = object.position + 1; // <- this is an error, and should
                                       //    have been object.position.x
                                       //    however it fails *silently*,
                                       //    rather than loudly

newPosition *= 2;                      // <- this doesn't raise any errors either.
                                       //    this code is actually ok if the
                                       //    previous line had been correct
kibibu asked 2020-02-29T12:21:31Z
5个解决方案
37 votes

要回答询问的问题:

是否有任何现代浏览器会引起NaN传播异常(即,对NaN乘以或加一个数字),或者可以对其进行配置?

否。JavaScript是一种非常宽容的语言,不需要在意是否要将Math.PI与“ potato”相乘(提示:这是NaN)。 它只是关于我们开发人员必须处理的语言的坏部分(或好部分,具体取决于您的观点)之一。

解决您可能会问这个问题的错误(大概),在对象上使用getter和setter是实施此错误并避免出现此类错误的一种可靠方法。

Rob M. answered 2020-02-29T12:38:36Z
26 votes

以下代码可能会对您有所帮助。

为了完全解决此问题,我认为我们需要像valueOf这样的东西。我们可以重新加载'+-/ *'之类的运算符,并检查操作数是否为数字,如果不是,则抛出Error。

作为部分解决方案,当JavaScript执行类似“ a + b”的操作时,它将调用从Object.prototype继承的valueOf方法,我们可以重写Object.prototype.valueOf

Object.prototype.originalValueOf = Object.prototype.valueOf;

Object.prototype.valueOf = function() {
  if (typeof this !== 'number') {
    throw new Error('Object is not a Number');
  }

  return this.originalValueOf();
}

var a = 1 + 2; // -> works
console.log(a); // -> 3

var b = {};
var c = b + 2; // -> will throw an Error

(提示:您可以删除生产中的代码,并将其添加到您的开发环境中。)

Jerry answered 2020-02-29T12:39:10Z
10 votes

最简单的方法是使用简短的方便函数,每次都可验证表达式的结果

我知道这不是您要寻找的答案,但这是javascript的性质,您不能伤心地更改它

function v(a){ if(isNaN(a)) throw "error"; return a; }
var test = v(100 * "abc");
answered 2020-02-29T12:39:35Z
2 votes

我认为在这种情况下,getter和setter会派上用场。

以下是一个伪代码示例,仅供您参考。

//Inside your Object class code.
function getPosition() {

  //You don't want the property "position" to be NaN, right?
  if(isNaN(this.position)) 
    throws "NaN is not a correct numerical value!";

  return this.position;

}


//Somewhere in your code
var newPosition = object.getPosition() + 1; //raises an exception.

我认为这比实现伪造的运算符重载更好,并使事情更复杂。

Jason answered 2020-02-29T12:40:04Z
2 votes

我知道这是一个老话题,但是我认为您的问题可能有一个非常简单的答案。 您可以为以下语句创建一个函数或将其内联添加。

JavaScript对于某些值具有一些独特的行为。 这些独特的行为之一围绕着非数字值xNaN的值将不等于包括NaN本身的任何其他值。 因此,以下语句:

if(x != x) {
    throw "Value is NaN!";
}

仅当x的值为NaN时,true才成立。

War10ck answered 2020-02-29T12:40:33Z
translate from https://stackoverflow.com:/questions/20534887/break-on-nan-in-javascript