Why and how does ([![]]+[][[]])[+!+[]+[+[]]] evaluate to the letter “i”?
在阅读Dzone上发表的这篇文章时,我发现了马库斯·拉格伦最初在Twitter上发布的一小段javascript。
下面的代码显然打印了字符串
1 | (![]+[])[+[]]+(![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]; |
这涉及到隐式类型转换,我正试图理解这一行的解释方式。
我把每个角色都隔离了
(![]+[])[+[]] 打印"f" 。(![]+[])[+!+[]] 打印"a" 。([![]]+[][[]])[+!+[]+[+[]]] 打印"i" 。(![]+[])[!+[]+!+[]] 打印"l" 。
我还设法将返回每个字母的表达式与
根据第11.6.1点,
同样,这里唯一的区别是方括号部分的附加转换(计算为数字以指向字符串
如上文所述,
根据第9.2节和第11.4.9节的定义,
让我头疼的是字母
如果可能的话,我希望每个步骤都包含到基础ECMAScript规则的链接。
我发现最神秘的部分是:
如果你稍微重写一下,你的神秘部分就不那么神秘了:
1 | [][''] |
由于
至于实际字母,将表达式分成两个主要部分:
- 字符串
([![]]+[][[]]) :[![]] 为[false] 。[][[]] 为undefined 。- 把它们加在一起就得到了
"falseundefined" 。
- 指数:
[+!+[]+[+[]]] 。一些空白和括号将使操作更加清晰:[+(!(+[])) + [+[]]] :[+[]] 为[0] 。+[] 将[] 强制为整数,所以得到0 。!+[] 将0 强制为布尔值并将其否定,因此得到true 。+!+[] 强制true 为整数,所以得到1 。- 把它们加在一起,就得到了
["10"] 。
当使用字符串访问数组的属性并且该字符串恰好是数组的元素时,该字符串将强制转换为整数,然后返回数组的实际元素:
1 2 3 4 | > [1, 2, 3]["0"] 1 > [1, 2, 3]["1"] 2 |
所以你的最终结果是:
1 2 | >"falseundefined"["10"] "i" |
请阅读此答案,了解有关
你发现自己的那个。
很抱歉之前的回答,我完全误解了你的评论。