在浏览各个鱼塘时,遇到了一个贼nb的表达式

([][[]] + []) [+!![]] + ([] + {})[+!![] + +!![]]

而且,它不但表达式nb,它结果也很nb

表达式结果

哈哈哈,下面就来把这个表达式给拆分掉

从头开始,首先,[][[]],前面是个空数组,这个的意思是读取这个空数组的某个索引,但是这里面的索引是个数组,数组不能做索引,所以就会把这个数组转为字符串

转为字符串

所以就得到了这个[][''],读取这个空数组里面索引为空字符串的值,但是哪有这个值,所以就返回了一个undefined,所以现在就得到了这个表达式

(undefined + []) [+!![]] + ([] + {})[+!![] + +!![]]

下面我们来看这个,undefined + [],JavaScript 在某些操作符和内置函数中,处理原始类型和对象时会尝试将对象转换为原始类型,这是因为这些操作符和函数预期要处理的是原始值,而不是对象。所以这个数组要转成原始值,得到一个'',所以变成了undefined + '',得到的结果是'undefined'

在JavaScript 引擎会尝试将其解释为一个表达式,但由于括号内没有函数名或表达式,它实际上会忽略括号,并返回括号内的值,所以('undefined')得到了'undefined',所以现在的表达式是这样的

'undefined'[+!![]] + ([] + {})[+!![] + +!![]]

'undefined'[+!![]],这个又是读取'undefined'索引的值,下面我们来看这个索引 !![],任何一个东西前面加两个!,相当于是把这个东西转成布尔值,任何对象转成布尔值都是true,所以这里得到'undefined'[+true],在布尔值的前面加+作用是把布尔值转化成数字,因为true为1,false为0,所以+ture得到的结果为1,所以'undefined'[1]得到的值为'n'

得到值n

需要注意的是,如果使用二元加号 +,得到的结果就不同了,比如true + true得到的结果为2,这是因为在计算时它也会进行隐式类型转换,但是转换的规则稍有不同,因为它涉及到两个操作数

所以现在就得到了这样的表达式

'n' + ([] + {})[+!![] + +!![]]

下面来看这个,[] + {},当加号两边都是非原始时怎么办,转成原始类型,空数组转为原始是'',空对象转为原始是[object Object],所以'' + [object Object]得到的结果是'[object Object]',所以就得到了这个表达式

'n' + '[object Object]'[+!![] + +!![]]

刚刚已经说过了 +!![]得到的值是1,所以得到的表达式是这样的

'n' + '[object Object]'[2]

由于'[object Object]'[2]得出来的结果是'b','n'+'b'就得到了这个表达式的结果

表达式的结果

哈哈哈,真的很有趣

好啦,Goodbye~

最后修改:2024 年 05 月 29 日
如果觉得我的文章对你有用,请随意赞赏