在JavaScript中打破NaN

是否有任何现代浏览器引发NaN传播的exception(即将数字乘以或添加到NaN),还是可以configuration为这样做呢?

沉默的NaN传播是一个可怕的阴险的错误来源,我希望能够尽早发现它们,即使在性能上也是如此。


这里有一个use strict的例子, jshint等。 不会拿起:

 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 

要回答这个问题:

是否有任何现代浏览器引发NaN传播的exception(即将数字相乘或添加到NaN),还是可以configuration为这样做呢?

不。Javascript是一个非常宽容的语言,并不关心,如果你想乘“马铃薯” Math.PI (提示:这是NaN )。 这只是我们开发人员必须处理的语言中的一个糟糕的部分(或者根据您的观点来看是好的部分)。

解决你提出这个问题的错误(大概是这样),在你的对象上使用getter和setter是一个强制执行的可靠方法,也可以防止你犯这样的错误。

下面的代码可能会帮助你。

为了完全解决这个问题,我认为我们需要像operator reload 。 我们可以像'+ – / *'一样重新加载运算符,并检查操作数是否为数字,如果不是,则抛出Error。

作为一个部分的解决scheme,当JavaScript执行像“a + b”这样的操作时,它将调用inheritance自Object.prototypevalueOf方法,我们可以重写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 

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

最简洁的方法是每次都有一个简短的函数来validationexpression式的结果

我知道这不是你正在寻找的答案,但这是JavaScript的本质,你不能伤心地改变它

 function v(a){ if(isNaN(a)) throw "error"; return a; } var test = v(100 * "abc"); 

我认为这是一个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. 

我认为这比实施假操作符重载并使事情更复杂更好。

我知道这是一个古老的线程,但我认为可能有一个超级简单的答案你的问题。 你可以为下面的语句创build一个函数,或者直接添加它。

JavaScript对于某些值有一些独特的行为。 其中一个独特的行为围绕着非数值或NaNNaN的值不会与包括NaN在内的任何其他值相比较。 出于这个原因,下面的声明:

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

当且仅当 x的值是NaN才会成立。