高一技术宅怒拆雷霆JS代码:([] [[]] + [])[+!![]] + ([] + {})[+!![] + +!![]]凭啥等于"nb"?
- 引子:刷视频刷到个“雷霆代码”
上周刷B站,突然刷到渡一Web前端的视频,标题写着“这个表达式是真‘nb’”。我心想:JS还能这么玩?点进去一看,好家伙,屏幕上赫然出现一行代码:
([] [[]] + [])[+!![]] + ([] + {})[+!![] + +!![]]
然后控制台输出 "nb"。我当场就跪了:这不科学啊!一堆括号、方括号、感叹号、加号,怎么就能拼出“nb”呢?作为一个高一技术宅,我的中二之魂燃起来了,必须手撕这个雷霆代码!
- 拆解第一步:把代码切开
这代码其实分成两半,中间用 + 连接:
左边:([] [[]] + [])[+!![]]
右边:([] + {})[+!![] + +!![]]
分别算出左右的结果,再拼起来。那我们就左边先来。
- 左边魔法:([] [[]] + [])[+!![]]
3.1 先看 ([] [[]] + [])
这里有个神奇的操作:[] [[]]。
· 第一个 [] 是一个空数组。
· 第二个 [[]] 是一个数组,里面包含一个空数组。把它当作属性名去访问第一个数组?
在JS中,方括号里的东西如果不是数字,会被自动转成字符串。
[[]].toString() 会得到什么?空数组转字符串是空串 "",里面只有一个空数组,没有逗号,所以结果是 ""。
所以 [] [[]] 就相当于 []."",也就是访问空数组的 "" 属性。数组没有这个属性,所以结果是 undefined。
接下来 undefined + []:
· undefined 转字符串是 "undefined"
· [] 转字符串是 ""(空数组变空串)
两者相加得到 "undefined"。
所以 ([] [[]] + []) 的结果就是字符串 "undefined"。
3.2 再看后面的 [+!![]]
这个 !![] 是啥?
[] 是个空数组,但它是个对象,在布尔环境里,对象都是 true。
![] 就是 false,!![] 就是 true。
前面再加个 +:+true 会把 true 转成数字 1。
所以 [+!![]] 实际上就是 [1],即取前面字符串的索引1(第二个字符)。
3.3 左边最终结果
"undefined"[1] 是啥?
"undefined" 的字符索引:
0: 'u'
1: 'n'
2: 'd'
3: 'e'
4: 'f'
5: 'i'
6: 'n'
7: 'e'
8: 'd'
索引1就是 'n'。
左边搞定,得到了 'n'。
- 右边魔法:([] + {})[+!![] + +!![]]
4.1 先算 ([] + {})
空数组 [] 转字符串是 ""。
空对象 {} 转字符串是 "[object Object]"(这是JS的内置行为)。
两者一加,得到 "[object Object]"。
4.2 再看 [+!![] + +!![]]
前面已经知道 +!![] 是 1。
两个 1 相加,就是 2。
4.3 右边最终结果
"[object Object]"[2] 是啥?
字符串 "[object Object]" 索引:
0: '['
1: 'o'
2: 'b'
3: 'j'
4: 'e'
5: 'c'
6: 't'
7: ' '
8: 'O'
…
索引2就是 'b'。
右边得到 'b'。
- 左右合并
'n' + 'b' = "nb"!
完美,终于明白为啥是“nb”了。
这代码就像魔法一样,把 undefined 和 [object Object] 这两个字符串的特定位置抠出来,拼成了“nb”。
- 总结:这波操作告诉我们什么?
- JS的类型转换太野了:数组转字符串、对象转字符串、布尔转数字,处处都是坑,但也被大佬玩出了花。
- 方括号里什么都能塞:塞数组、塞布尔表达式,最后都会变成字符串或数字去索引。
- 学JS不仅要会写,还要会拆:遇到这种雷霆代码,一步步拆解,会发现其实就是基础知识的组合。
最后,感谢渡一Web前端的视频让我学到了这波骚操作。以后我也要在代码里埋这种梗,让后人看到直呼“nb”!(不过生产环境这么写怕不是会被打死)
高一技术宅,拆解完毕,撤退!

Comments NOTHING