我在摆弄parseInt,看看它如何处理尚未初始化的值,我偶然发现了这个宝石。下面的情况发生在任何基数24或以上。

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

我在IE, Chrome和Firefox中测试了它,它们都是正确的,所以我想它一定是在规范的某个地方。快速的谷歌搜索没有给我任何结果,所以我在这里,希望有人能解释。

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

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

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


博士tl;

解释为什么parseInt(null, 24) === 23是一个真语句。


当前回答

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

js> parseInt(null, 36)
1112745

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

其他回答

parseInt( null, 24 ) === 23

等于

parseInt( String(null), 24 ) === 23

这相当于

parseInt( "null", 24 ) === 23

以24为基数的数字是0,1,2,3,4,5,6,7,8,9,a, b, c, d, e, f,…, n。

语言规范说

如果S包含任何不是基数- r数字的字符,则设Z是S的子字符串,由第一个这样的字符之前的所有字符组成;否则,设Z为S。

这是确保像15L这样的c风格整数字面量正确解析的部分, 所以上面等价于

parseInt( "n", 24 ) === 23

n是上面数字列表中的第23个字母。

Q.E.D.

parseInt使用字母数字表示,那么在base-24中“n”是有效的,但“u”是无效字符,那么parseInt只解析值“n”....

parseInt("n",24) -> 23

举个例子,试试这个:

alert(parseInt("3x", 24))

结果将是“3”。

Mozilla告诉我们:

function parseInt converts its first argument to a string, parses it, and returns an integer or NaN. If not NaN, the returned value will be the decimal integer representation of the first argument taken as a number in the specified radix (base). For example, a radix of 10 indicates to convert from a decimal number, 8 octal, 16 hexadecimal, and so on. For radices above 10, the letters of the alphabet indicate numerals greater than 9. For example, for hexadecimal numbers (base 16), A through F are used.

在规范中,15.1.2.2/1告诉我们,到字符串的转换是使用内置的ToString执行的,它(根据9.8)将产生“null”(不要与ToString混淆,后者将产生“[object Window]”!)

因此,让我们考虑parseInt("null", 24)。

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

现在,在取出十进制23之后,解析就会停止,因为“u”在以24为进制的系统中找不到:

如果S包含任意一个字符 不是基数r,则设Z为 S的子串,由所有组成 第一个字符之前的字符 字符;否则,设Z为s。[15.1.2.2/11]

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

我猜null会被转换成字符串"null"因此,在'base24'中n实际上是23(在'base25'+中相同),u在'base24'中无效,因此字符串null的其余部分将被忽略。这就是为什么它输出23,直到u在'base31'中生效。

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

js> parseInt(null, 36)
1112745

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