Rob*_*ert 226 javascript parseint
好吧,所以我正在搞乱parseInt来看看它如何处理尚未初始化的值,我偶然发现了这个宝石.对于任何24或以上的基数,都会发生以下情况.
parseInt(null, 24) === 23 // evaluates to true
Run Code Online (Sandbox Code Playgroud)
我在IE,Chrome和Firefox中对它进行了测试,它们都是警告的,所以我认为它必须在某个地方的规范中.一个快速的谷歌搜索没有给我任何结果所以我在这里,希望有人可以解释.
我记得听过他说的Crockford演讲,typeof null === "object"
因为疏忽导致Object和Null在内存中有一个几乎相同的类型标识符,或者沿着这些行,但我现在找不到那个视频了.
试一试: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
是真实的陈述.
Ign*_*ams 239
它正在转换null
为字符串"null"
并尝试转换它.对于基数0到23,它没有可以转换的数字,因此它返回NaN
.在24处,"n"
将第14个字母添加到数字系统.在31处,"u"
添加第21个字母,并且可以解码整个字符串.在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
Run Code Online (Sandbox Code Playgroud)
Lig*_*ica 118
Mozilla 告诉我们:
function parseInt 将其第一个参数转换为字符串,解析它,并返回一个整数或NaN.如果不是NaN,则返回的值将是作为指定基数(基数)中的数字的第一个参数的十进制整数表示.例如,10的基数表示从十进制数转换,8八进制,十六进制16,依此类推.对于大于10的基数,字母表中的字母表示大于9的数字.例如,对于十六进制数字(基数16),使用A到F.
在规范中,15.1.2.2/1告诉我们转换为字符串是使用内置函数执行的ToString
(根据9.8)产生"null"
(不要混淆toString
,这会产生"[object Window]"
!).
所以,让我们考虑一下parseInt("null", 24)
.
当然,这不是一个完整的base-24数字字符串,但是"n"是:它是十进制23.
现在,停止解析十进制23被拉出后,因为"u"
没有在基本-24系统中发现:
如果S包含任何不是radix-R数字的字符,那么让Z为S的子字符串,由第一个这样的字符之前的所有字符组成; 否则,让Z为S. [15.1.2.2/11]
(这就是为什么parseInt(null, 23)
(和更低的基数)给你NaN
而不是23:"n"
不在base-23系统中.)
Dav*_*nco 79
Ignacio Vazquez-Abrams是正确的,但让我们看看它是如何工作的 ......
来自15.1.2.2 parseInt (string , radix)
:
调用parseInt函数时,将执行以下步骤:
- 让inputString为ToString(string).
- 设S是一个新创建的inputString子串,由不是StrWhiteSpaceChar的第一个字符和该字符后面的所有字符组成.(换句话说,删除前导空格.)
- 让标志为1.
- 如果S不为空并且S的第一个字符是减号 - 则让符号为-1.
- 如果S不为空并且S的第一个字符是加号+或减号 - ,则从S中删除第一个字符.
- 设R = ToInt32(基数).
- 让stripPrefix为true.
- 如果R≠0,那么a.如果R <2或R> 36,则返回NaN.湾 如果R≠16,则让stripPrefix为false.
- 否则,R = 0 a.设R = 10.
- 如果stripPrefix为true,则a.如果S的长度至少为2并且S的前两个字符是"0x"或"0X",则从S中删除前两个字符并让R = 16.
- 如果S包含任何不是radix-R数字的字符,那么让Z为S的子字符串,由第一个这样的字符之前的所有字符组成; 否则,让Z为S.
- 如果Z为空,则返回NaN.
- 令mathInt为数字整数值,由Z表示为基数-R表示法,使用字母AZ和az表示数值为10到35的数字.(但是,如果R为10且Z包含超过20位有效数字,则每个有效数字在实现的选项中,20之后的数字可以被0数字替换;并且如果R不是2,4,8,10,16或32,则mathInt可以是对数学整数的依赖于实现的近似以radix-R表示法用Z表示的值.)
- 设number为mathInt的Number值.
- 返回标志×数字.
注意parseInt可能只将字符串的前导部分解释为整数值; 它忽略任何不能被解释为整数表示法的一部分的字符,并且没有指出任何这样的字符被忽略.
这里有两个重要的部分.我加粗了他们两个.首先,我们必须找出其toString
代表性null
.我们需要Table 13 — ToString Conversions
在第9.8.0节中查看该信息:
很好,所以现在我们知道在toString(null)
内部做一个'null'
字符串.太好了,但它究竟如何处理在提供的基数内无效的数字(字符)?
我们看上面15.1.2.2
,我们看到以下说法:
如果S包含任何不是radix-R数字的字符,那么让Z为S的子字符串,由第一个这样的字符之前的所有字符组成; 否则,让Z为S.
这意味着我们处理指定基数之前的所有数字并忽略其他所有数字.
基本上,做parseInt(null, 23)
同样的事情parseInt('null', 23)
.将u
导致两个l
的被忽略(即使它们的基数23的一部分).因此,我们只能解析n
,使整个语句成为同义词parseInt('n', 23)
.:)
无论哪种方式,很棒的问题!
Mik*_*uel 33
parseInt( null, 24 ) === 23
Run Code Online (Sandbox Code Playgroud)
相当于
parseInt( String(null), 24 ) === 23
Run Code Online (Sandbox Code Playgroud)
这相当于
parseInt( "null", 24 ) === 23
Run Code Online (Sandbox Code Playgroud)
基数24的数字是0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,...,n.
语言规范说
- 如果S包含任何不是radix-R数字的字符,那么让Z为S的子字符串,由第一个这样的字符之前的所有字符组成; 否则,让Z为S.
这是确保C样式整数文字15L
正确解析的部分,所以上面相当于
parseInt( "n", 24 ) === 23
Run Code Online (Sandbox Code Playgroud)
"n"
是上面数字列表的第23个字母.
QED
Flo*_*ern 16
我想null
转换成一个字符串"null"
.所以,n
实际上是23
在"base24"(在"base25" +相同),u
是在"base24",使字符串的其余部分无效null
将被忽略.这就是为什么它输出23
直到u
'base31' 才有效.
小智 7
parseInt使用字母数字表示,然后在base-24"n"有效,但"u"是无效字符,那么parseInt只解析值"n"....
parseInt("n",24) -> 23
Run Code Online (Sandbox Code Playgroud)
例如,试试这个:
alert(parseInt("3x", 24))
Run Code Online (Sandbox Code Playgroud)
结果将是"3".
归档时间: |
|
查看次数: |
15486 次 |
最近记录: |