parseInt(null, 24) === 23...等等,什么?

2022-08-30 00:53:56

好吧,所以我在用parseInt搞砸,看看它如何处理尚未初始化的值,我偶然发现了这个宝石。对于任何基数24或以上,都会发生以下情况。

parseInt(null, 24) === 23 // evaluates to true

我在IE,Chrome和Firefox中测试了它,它们都提醒真实,所以我认为它一定在规范的某个地方。快速的谷歌搜索没有给我任何结果,所以我在这里,希望有人可以解释。

我记得听了Crockford的一次演讲,他说是因为一个疏忽导致Object和Null在内存中具有几乎相同的类型标识符或类似的东西,但我现在找不到那个视频。typeof null === "object"

试试看:http://jsfiddle.net/robert/txjwP/

编辑更正:较高的基数返回不同的结果,32 返回785077
编辑 2 来自 zzzzBov:[24...30]:23, 31:714695, 32:785077, 33:859935, 34:939407, 35:1023631, 36:1112745


tl;博士

解释为什么是真实的陈述。parseInt(null, 24) === 23


答案 1

它正在转换为字符串并尝试将其转换。对于基数 0 到 23,没有可以转换的数字,因此它返回 。在 24 处,第 14 个字母被添加到数字系统中。在 31 处,添加第 21 个字母,可以对整个字符串进行解码。在37上,不再有任何可以生成的有效数字集,并且返回NaN。null"null"NaN"n""u"

js> parseInt(null, 36)
1112745

>>> reduce(lambda x, y: x * 36 + y, [(string.digits + string.lowercase).index(x) for x in 'null'])
1112745

答案 2

Mozilla 告诉我们

函数 parseInt 将其第一个参数转换为字符串,对其进行分析,并返回整数或 NaN。如果不是 NaN,则返回值将是第一个参数的十进制整数表示形式,该表示形式取为指定基数(基数)中的数字。例如,基数 10 表示从十进制数、8 个八进制数、16 个十六进制数转换而来。对于大于 10 的菊数据按字母表示大于 9 的数字。例如,对于十六进制数(以 16 为基数),使用 A 到 F。

在规范中,15.1.2.2/1 告诉我们,转换为字符串是使用 内置的 ,这(根据9.8)产生(不要与混淆,这将产生!ToString"null"toString"[object Window]"

因此,让我们考虑一下.parseInt("null", 24)

当然,这不是一个完整的以24为基数的数字字符串,但“n”是:它是十进制的23

现在,解析在十进制 23 被拉出后停止,因为在 base-24 系统中找不到解析:"u"

如果 S 包含任何不是基数-R 数字的字符,则设 Z 是 S 的子字符串,由第一个此类字符之前的所有字符组成;否则,设 Z 为 S. [15.1.2.2/11]

(这就是为什么(和较低的基数)给你而不是23:不在23基数系统中。parseInt(null, 23)NaN"n"