为什么eval(“475957E-8905”)==“475957E-8905”是真的?
我用nodeJs做了一个程序,生成如下的代码
eval("XXXXXX") == "XXXXXX"
它工作得很好,但是他一时间给了我这个:
eval("475957E-8905") == "475957E-8905"
我用Firebug来testing它,结果是true
。但我不明白为什么。
当然, eval("475957E-8905")
返回0
但是为什么0 == "475957E-8905"
?
这个谜题有两个部分:使用==
浮点数和types不敏感的比较。
首先, 475957E-8905
评估为浮点数475957 * 10 ^ -8905
,这是令人难以置信的小; 以浮点forms,由于javascript的精度限制,它与0
相同。 所以, eval("475957E-8905")
返回0
。
现在,为拼图的第二部分。
==
表示types不必匹配,所以nodejs(就像任何JavaScript引擎)试图转换其中的一个,以便它们可以比较它们。
由于eval("475957E-8905")
返回0
,因此它会尝试将"475957E-8905"
转换为整数。 正如我们所见,那也是0
。 因此,比较是0 == 0
,这是真的。
请注意,如果您执行eval("3") == "3"
或eval("3") == 3
,则会发生同样的情况,在每种情况下,都将string转换为数字并进行比较。
避免这个问题
你可以像这样强制types敏感的比较:
eval("475957E-8905") === "475957E-8905"
它返回false,因为===
告诉javascript引擎只有在types和值都匹配时才返回true。
JavaScript必须将您的string“475957E-8905”转换为数字才能进行比较。 当它这样做时,它也将“475957E-8905”转换为0。 所以,0 == 0;
如你看到的:
"475957E-8905" == 0
是真的。 基本上你把eval
语句“475957E-8905”编成一个数字,然后把其他的“475957E-8905”转换成数字进行比较。 最后,他们俩都发生了完全相同的转换过程,他们都是0。
使用===
来比较types,以获得更多信息:
JavaScript有严格的和types转换的平等比较。 对于严格的平等,被比较的对象必须具有相同的types,并且:
- 两个string具有相同的字符序列,长度相同,并且在相应的位置上具有相同的字符时,它们是严格相等的。
- 两个数字在数字上相等时(数字值相同)严格相等。 NaN不等于任何东西,包括NaN。 正和负的零相等。
- 如果两个布尔操作数都为真或两者都为假,则两个布尔操作数严格相等。
- 如果两个对象引用同一个对象,则两个对象严格相等。
- 空和未定义的types是==(但不是===)。 [即Null ==未定义(但不为空===未定义)]
检查这个文件