我有兴趣了解JavaScript的内部.我试图阅读SpiderMonkey和Rhino的源代码,但是我的头脑很复杂.
我问的原因是:为什么会这样
(![]+[])[+!![]+[]]
生产 "a"
(Å=[],[µ=!Å+Å][µ[È=++Å+Å+Å]+({}+Å)[Ç=!!Å+µ,ª=Ç[Å]+Ç[+!Å],Å]+ª])()[µ[Å]+µ[Å+Å]+Ç[È]+ª](Å)
生产alert(1)
?
资料来源:http://sla.ckers.org/forum/read.php?24,32930,page = 1.
在该论坛上还有更多关于JavaScript奇怪的例子,我想从编程的角度了解它在Web应用程序安全性方面的工作原理.
如果你想了解为什么那些奇怪的表达式会像他们一样工作,你可以打开firebug控制台并自己做实验.我没有和我得到的![]
是false
,!![]
是true
,增加一个阵列为布尔值(false+[]
或true+[]
)产生该值的字符串版本(false+[]="false"
).
这样表达式归结为:
"false"["1"]
这显然是"一个"
为什么(![]+[])[+!![]+[]]
生产"一个"
一步一步:这是在:(![]+[])
和[+!![]+[]]
.解析.第一位已经由artemb解释:[]
是一个数组.否定它,![]
评估为布尔值,false
- 这是!
当它应用于null
未定义或未定义的东西时的工作方式.再次如artemb所指出的那样,附加这会+[]
强制将布尔值转换为字符串.那是因为它+
是一个字符串连接运算符.false
然后将布尔值转换为其字符串表示形式,"false"
.
然后,第二位,[+!![]+[]]
.首先,外部[
和]
服务来处理前面的字符串,我们刚刚提取的字符串等于"false"
字符数组.通过在[
和中放入一个整数索引]
,可以获得特定索引处的字符.那么剩下的就是+!![]+[]
这个由4个部分组成:+
,!![]
,+
和[]
.首先!![]
进行评估.我们已经看到这![]
是一个布尔值,false
所以前面的另一个!
否定它和收益率true
.接下来发生的事情是+
in +!![]
得到应用,并通过应用+
它将布尔值true
转换为数字表示,即.)1
(所以+true
是1
+[]
内容再次从那个1
屈服中产生一个字符串,"1"
但它实际上没有意义,更短的表达式(![]+[])[+!![]]
已经产生a
.追加+[]
也没有伤害,结果表达只是["1"]
代替[1]
.我的预感是,当[]
应用于数组时,内部的任何内容[]
都会被强制转换为数字,这"1"
将1
再次给出.所以无论哪种方式,+!![]+[]
计算结果为1
,使得最终表达式:"false"[1]
其中是说:在从字符串索引1给我的字符"false"
,并且由于缺省,数组在开始0
在JavaScript中,这是第二个字符"false"
,以及a
.