在JavaScript中打破NaN

kib*_*ibu 47 javascript nan

是否有任何现代浏览器引发NaN传播的异常(即将数字乘以或添加到NaN),或者可以配置为这样做?

沉默的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
Run Code Online (Sandbox Code Playgroud)

Rob*_* M. 37

要回答问题:

是否有任何现代浏览器引发NaN传播的异常(即将数字乘以或添加到NaN),或者可以配置为这样做?

不.Javascript是一种非常宽容的语言,并不关心你是否想要乘以Math.PI'马铃薯'(提示:它NaN).这只是我们开发人员必须处理的语言的一个不好的部分(或者很好的部分,取决于你的观点).

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


Jer*_*rry 26

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

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

作为部分解决方案,当JavaScript执行类似'a + b'的操作时,它将调用valueOf继承自的方法Object.prototype,我们可以重写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
Run Code Online (Sandbox Code Playgroud)

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

  • 讨厌,讨厌的想法!`.valueOf()`不仅仅被数字使用! (13认同)
  • 这会影响任何对象,不仅是数字,因此不是你想要使用的东西:( (4认同)
  • 将此添加到Chrome然后运行我的代码会崩溃选项卡和开发工具.还在探索! (3认同)

小智 10

最简洁的方法是使用一个简短的函数来每次验证表达式的结果

我知道这不是你要找的答案,但这是javascript的本质,你不能伤心地改变它

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