什么鬼?++[[]][+[]]+[+[]] === "10"

435 阅读3分钟

1.梦的开始

大早上刚睡醒,就被问了一个奇怪的问题: js代码 ++[[]][+[]]+[+[]] 解析出来是什么?(2个字符)


尽管这段奇怪的代码(++[[]][+[]]+[+[]])有点像原生js代码仔细看聊天内容发现还真的是有说js代码),
但我开始以为是像unicodebase64之类的特殊编码或加密,我一贯遇到js问题都会拿代码去浏览器跑一下🙄。本来以为跑出来会是一个错误,结果运行的结果又把我搞懵逼了👀


没有报错...,这居然是一段能被运行的原生js代码???,返回一个字符串 10!!!


2.解析过程


   2.1.梦幻开局😲

从上面的运行结果来看,我们可以得到一些有用的信息

  • 1.这段代码可以直接被执行
  • 2.返回值是一个字符串类型
  • 3.代码中没有明确的数字0-9,但有运算符+++,所以结果很可能是数字转为字符串
  • 4.和数组密切相关(不要问我为什么)

猜测:利用数组进行了一些奇怪(我不懂的都叫奇怪就对了)的操作


   2.2.拆分并逐步运行 ++[[]][+[]]+[+[]]😲

这串代码看着怪眼花的,试着拆分并去分别运行一下:

编号 代码 返回值的类型 运行结果(返回值)
串A ++[[]][+[]] Number 1
运算符 +
串B [+[]] Array [0]
串A+串B ++[[]][+[]]+[+[]] String "10"

我们将这段代码拆分成三段串A运算符加号,串B,分别运行串A串B后得到了
数字 1数组 [0],
但是数字数组也返回字符串(我居然一直不知道 T_T)


  [123]+2         //"1232"
  2+[123]         //"2123"
  [12,3]+2        //"12,32"
  [20,40,8]+4     //"20,40,84"
  ['我是',2]+4     //"我是,24"

好吧好吧,知识点get到了,奇怪的知识也增加了😥


   2.3.更深度的拆分😲

编号 代码 返回值的类型 运行结果(返回值)
串A1 ++[[]] (Uncaught)SyntaxError Invalid left-hand side expression in prefix operation
串A2 [+[]] Array [0]
串B [+[]] Array [0]

我们可以发现,串A2是等同于串B的,但为什么运行串A1的代码会返回一个SyntaxError呢?


   2.4.串A1错误的原因😲

串A1错误的原因,其实很简单,就是一个语法错误

  ++[1,2,3]      //错误
  ++[1,2,3][0]   //返回Number 2

3.大胆的想法


理解了上面的步骤,我产生了一个大胆的想法(仅个人理解)


  +[]          //0
  /*大胆的想法*/
  ++[0][0]     //1
  ++[null][0]  //1
  ++[false][0] //1
  /*细思极恐*/
     0  == false     //true
   null == false     //true
  false == false     //true
     [] == false     //true
  /*恍然大悟*/
  false == 0         //true
     [] == 0         //true

所以代码 ++[[]][+[]]+[+[]] 中的[]难道是成了0?
那么根据+[]等价于数字0,这串代码就变成了++[0][0]+[0]
数字 1+数组 [0],返回字符串 10


4.一些奇怪的操作的整理

你可能不会想看的,因为这属于额外篇幅,里面是一些Array或者Object加上Number的尝试

数组-运行结果
  /*使用变量让代码更直观些*/
  let a = [];
  +a;           //等同于+[];等同于串B           返回Number  0
  [a][+a];      //等同于[[]][+[]]              返回Array  []
  ++[a][+a];    //等同于++[[]][+[]],等同于串A   返回Number  1
  --[a][+a];    //等同于--[[]][+[]]            返回Number -1
对象-运行结果
  {a:1}+2     //2
  {a:100}+2   //2
  {a:1}-2     //-2
  {a:100}-2   //-2
  {'a':2}+2   //Uncaught SyntaxError: Unexpected token ':'

let b = {a:100}; b+2; //"[object Object]2"


5.小结

剪不乱,理还乱


   null + 1 //Number 1
  false + 1 //Number 1
               -[]  === -0           //true,不科学操作
  ++[[]][+[]]+[+[]] === ++[0][0]+[0] //true

作者个人认为是空数组[]被神秘的力量转为了数字0


  • 其实这个问题还满有趣的,有兴趣的小伙伴可以去研究一下,由于作者水平有限只能解释这么多了,
  • 以上仅作者个人观点,有待探究完善
  • 第一次写文章还蛮激动的,可能就是"太"啰嗦了一点😎

本文使用 mdnice 排版