为什么 Javascript 允许非数字算术

Why does Javascript allow arithmetic by non-numbers

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

结果 NaN, NaN, NaN

当然,由于 js 的动态特性,这不会抛出语法错误,但为什么至少不会抛出运行时错误?试图从中找出错误花了我大约 15 分钟。抛出异常不是总是可取的吗?

不是,请阅读 this 部分 11.5.1 应用 * 运算符(第一个要点)

If either operand is NaN, the result is NaN

Why does JS allow arithmetic with non-numeric values?

因为有些值可以隐式转换为数字:

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

Why does JS allow arithmetic with NaN without throwing?

因为 NaN 值是一个数字,它的目的正是进行无异常的错误传播(这对控制流来说非常困难)。此行为与使用浮点值的其他语言相同。

现在,当转换为数字导致 NaN 时,他们仍然可以例外,但这是不一致的,因为它不允许有目的地使用 new Number(NaN) 之类的东西。如果你想要这样的行为,你仍然可以拥有它:

 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")