JavaScript NaN Break

Is there any modern browser that throws exceptions when distributing NaN (i.e., multiplying or adding a number by NaN) or can it be configured to do this?

The silent distribution of NaN is a terrible and insidious source of errors, and I would like them to be able to detect them early, even with a decrease in performance.




Here is an example error that use strict , jshint et al. would not pick up:

 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 
+42
javascript nan
Dec 12 '13 at 4:10
source share
5 answers

To answer the question:

Is there any modern browser that throws exceptions when distributing NaN (i.e., multiplying or adding a number by NaN) or can it be configured to do this?

No. Javascript is a very forgiving language, and you don't care if you want to multiply Math.PI by "potato" (hint: it NaN ). This is only one of the bad parts (or good parts, depending on your point of view) regarding the language that we have to deal with developers.

Turning to the error in which you ask this question (presumably), using getters and setters in your objects is one of the reliable ways to ensure this, and also does not allow you to make such errors.

+36
Dec 12 '13 at 4:43
source share

Code can help you.

To solve this problem completely, I think we need something like operator reload . We can reload operators like "+ - / *" and check if the operand is a number, if not, and then throw an error.

As a partial solution, when JavaScript performs an operation of type "a + b", it is called by the valueOf , which inherits from Object.prototype , we can rewrite 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 

(hint: you can delete the generated code and add it to your development environment.)

+27
Dec 12 '13 at 5:05
source share

The cleanest way to do this is to have a short convenient function that checks the result of an expression each time

I know that this is not the answer you are looking for, but it is the nature of javascript, and you cannot change it.

 function v(a){ if(isNaN(a)) throw "error"; return a; } var test = v(100 * "abc"); 
+10
Dec 12 '13 at 5:11
source share

I think this is a situation where getters and setters come in handy.

Below is an example psuedo code to give you an idea.

 //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. 

I think this is better than implementing a fake operator overload and complicating the situation.

+2
Dec 12 '13 at 4:42
source share

I know this is an old thread, but I think there might be a very simple answer to your question. You can either create a function for the statement below, or add it to a string.

JavaScript has some unique behaviors for certain values. One of these unique actions revolves around a non-number or NaN value. The NaN value will not be compared with any other value, including NaN . For this reason, the following statement:

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

will contain true if and only if x is NaN .

+1
Oct 08 '14 at 18:03
source share



All Articles