在JavaScript中突破NaN
是否有任何现代浏览器会在NaN传播时引发异常(即将数字乘以或添加到NaN),或者可以配置为引发异常 无声的NaN传播是一个可怕而阴险的bug来源,我希望能够及早发现它们,即使是在性能下降的情况下在JavaScript中突破NaN,javascript,nan,Javascript,Nan,是否有任何现代浏览器会在NaN传播时引发异常(即将数字乘以或添加到NaN),或者可以配置为引发异常 无声的NaN传播是一个可怕而阴险的bug来源,我希望能够及早发现它们,即使是在性能下降的情况下 下面是一个示例bug,使用strict,jshint等都不会出现: object = new MyObject(); object.position.x = 0; object.position.y = 10; // ... lots of code var newPosition = objec
下面是一个示例bug,
使用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
object=newmyobject();
object.position.x=0;
object.position.y=10;
// ... 很多代码
var newPosition=object.position+1;// 我认为在这种情况下,getter和setter会派上用场
下面是一个psuedo代码示例,旨在为您提供一个想法
//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.
我认为这比实施假运算符重载要好,使事情变得更复杂。要回答问题:
是否有任何现代浏览器会在NaN传播时引发异常(即将数字乘以或添加到NaN),或者可以配置为引发异常
不。Javascript是一种非常宽容的语言,它不在乎你是否想用“土豆”乘以Math.PI
(提示:它是NaN
)。这只是美国开发人员必须处理的语言的一个不好的部分(或好的部分,取决于你的观点)
解决让您提出这个问题的bug(大概是这样的),在对象上使用getter和setter是一种很好的方法来实现这一点,并防止您犯类似的错误。下面的代码可能会对您有所帮助
为了完全解决这个问题,我认为我们需要类似于操作符重载的东西。我们可以重新加载像“+-/*”这样的运算符,并检查操作数是否为number,如果不是,则抛出错误
作为部分解决方案,当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
(提示:您可以在生产环境中删除代码,并将其添加到您的开发环境中。)最干净的方法是使用一个简单方便的函数,每次验证表达式的结果
我知道这不是你想要的答案,但这是javascript的本质,你无法改变它
function v(a){ if(isNaN(a)) throw "error"; return a; }
var test = v(100 * "abc");
我知道这是一个古老的线索,但我认为可能有一个超级简单的答案来回答你的问题。您可以为下面的语句创建一个函数,也可以内联添加它
JavaScript对于某些值有一些独特的行为。这些独特的行为之一是围绕非数字值或NaN
展开的。NaN
的值不会与任何其他值(包括NaN
本身)进行比较。因此,以下声明:
if(x != x) {
throw "Value is NaN!";
}
当且仅当x
的值为NaN
时,才会成立我真的不想每次添加任何数字时都在代码中加上isnan。在计算中使用数据之前,您不能确保数据正确吗?这是GIGO原则在起作用——这对Monads来说可能是一个例子吗?:)@杰克:你真的能读懂我的心思。但是-不。@zerkms与RUJordan的想法基本相同-自由使用一堆资产?我正在寻找一种方法来快速检测编码错误,而不是处理垃圾输入。我同意getter和setter,但你不应该期望isNaN
是任何方法,调用anything.isNaN()
会自动抛出异常是的,对不起。但这只是一个psuedo代码,可以给你一个想法。isFinite
是另一个方便的函数。有时,您希望防止传入诸如无限
或-无限
之类的内容!这是理想的!这在什么浏览器上工作?Chrome和Safari至少不允许替换本机原型这不仅会影响数字,而且会影响任何对象,因此您不想使用:(@Wesabi,我很高兴能获得性能成功,如果成功的话,我可以克服这些限制。不幸的是,我无法做到这一点。将其添加到Chrome中,然后运行我的代码会使选项卡和开发工具都崩溃。但仍在探索!讨厌的、讨厌的想法!.valueOf()
不仅仅用于数字!我接受这个答案,因为它最直接地回答了这个问题。然而,@Jerry的答案解决了使用对象执行数字操作的问题,这很好地解决了实际问题的大量情况(除了乘以未定义的
*3或类似情况)我会叫它number
或者别的什么,但这看起来像是typeof(100*“abc”)
返回“number”
,因为具有讽刺意味的是NaN
是一个数字。你想要isNaN()
。