Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Javascript allow arithmetic by non-numbers

var i=0;
var a={};
console.log(i*a);
console.log(0*{});
console.log({}*{});

results NaN, NaN, NaN

Ofcourse this can't throw a syntax error because of the dynamic natue of js, but why doesn't this at least throw a runtime error? Trying to find a bug from this took me ~15 minutes. Wouldn't throwing an exception always be desirable?

like image 443
Khlorghaal Avatar asked Jun 22 '26 11:06

Khlorghaal


1 Answers

Why does JS allow arithmetic with non-numeric values?

Because there are values that can be converted to numbers implicitly:

new Number(15) + "7" * {valueOf() { return 2 }} // 29

Why does JS allow arithmetic with NaN without throwing?

Because the NaN value is a number, and it's purpose is exactly to do error propagation without exceptions (that are quite hard on control flow). This behavior is the same as in other languages that use floating-point values.

Now, they still could have made an exception when a conversion into a number led to NaN, but that's inconsistent because it disallows the purposeful usage of something like new Number(NaN). And if you want such a behavior, you can still have it:

 class MyNumber {
     constructor (x) {
         this.value = Number(x);
     }
     valueOf() {
         if (typeof this.value != "number" || isNaN(this.value))
             throw new TypeError("not exactly a number");
         return this.value;
     }
 }

 new MyNumber(15) * new MyNumber("areadfsdf")
like image 68
Bergi Avatar answered Jun 25 '26 01:06

Bergi