扫一扫下方二维码,关注本站官方公众号
获取永久解锁本站全部文章的验证码
还能不定期领现金红包

一行神奇的 javascript 代码-Go语言中文社区

一行神奇的 javascript 代码


(!(~+[])+{})[--[~+""][+[]]*[~+[]] + ~~!+[]]+({}+[])[[~!+[]]*~+[]]

运行这段代码,结果有点意外。



其实这主要是运用到了js的类型转换的基本原理。下面就揭秘“”sb“”是如何炼成的。

  1. 首先是js运算符的优先级。因为这么长的一段代码,分析起来比较困难。我们必须得根据优先级把这段代码分成许多小段,然后各个击破。js运算符的优先级从高到低排列如下:
运算符说明
   .   []   ()字段访问、数组索引、函数调用、表达式分组
++  --  -  ~  !  delete  new  typeof  void一元运算、返回数据类型、创建对象、未定义的值
*  /   %乘、除、取余
+   -   相加、相减、字符串串联
<<   >>   >>>移位
<   <=   >   >=   instanceof小于、小于或等于、大于、大于或等于、是否为特定类型的实例
==   !=   ===   !==相等、不相等、全等、不全等
&按位与
^按位异或
|按位或
&&逻辑与
||逻辑或
?:条件运算
=   OP=赋值、赋值运算(如+=)
多个计算
按照上述表格中的运算符优先级,对代码进行分割:


 运算符用红色标出,其中中括号[]也是亿个运算符,用来通过索引访问数组项,也可以访问字符串中的子字符,类似于charAt()方法。如:‘abcd’[1],返回‘b’.而且由上表可知,中括号的优先级是最高的。
2. js类型转换。当操作符两边的操作数类型不一致或者不是基本类型时,需要进行类型准换。
  • 非基本类型转换为Number型,首先调用obj.valueOf()方法,若结果是基本类型,返回。否则,调用obj.toString()方法,如果是基本类型,返回。否则,抛出错误。
  • 非基本类型转换为String类型,首先调用obj.toString()方法,若是基本类型,返回。否则,调用obj.valueOf()方法,若返回是基本类型,返回。
  • 基本类型转Number类型。
参数结果
undefinedNaN
null+0
booleantrue转换为1,false转换为0
number无需转换
string解析为数字
  • 基本类型转String类型。
参数结果
undefined‘undefined’
null'null'
boolean'true'或者‘false’
number数字直接转换为字符串
string无需转换
接着从下往上一次对分割的代码求值:
  • +[]   由于只有一个操作数[],因此需要将[]转换为Number类型。由于[]是非基本类型,所以先调用[].valueOf()方法,返回[],不是基本数据类型,继续调用toString()方法,返回一个空字符串"",再将空字符串转换为Number类型,得到0.所以,+[]最终的结果是0.
  • [~+""].由于只有一个操作数——空字符串,所以应转换为Number类型。首先,“”转换为Number类型为0,然后~运算符将数字取负然后减1.所以,[~+""]最终的结果是[-1].
  • --[~+""][+[]]。综合上述分析,该式变成了--[-1][0],即取数组的第0个元素,然后自减。所以结果为-2.
  • [~+[]]。+[]的结果为0,所以[~+[]]的结果为-1.
  • --[~+""][+[]]*[~+[]]。由上述可得该表达式变为-2*[-1]。由于运算符是*,因此需要将[-1]转换为Number类型。所以先调用valueOf()方法,返回[-1],不是基本类型,继续调用toString()方法,返回"-1",为字符串,接着将字符串转换为Number类型,得到-1.所以--[~+""][+[]]*[~+[]]最终的结果为2.
  • ~~!+[]。按照前述相同做法,+[]为0,!+[]结果为true。但由于只有一个操作数,true转换为Number后为1,然后对1取负后减1,得到-2,再将-2取负减1得到1,因此该表达式结果为1。
  • --[~+""][+[]]*[~+[]] + ~~  !+[]。由上述分析得该表达式的结果为2+1=3.
  • !(~+[])。由于~+[]的结果为-1,所有非0的值转换为boolean类型均为true,然后!取反后为false。
  • !(~+[])+{}。该表达式变成了false+{}.首先将{}转换为基本类型,首先调用valueOf()方法,返回自身{},不是基本类型。接着调用toString()方法,返回"[object Object]",然后将false转换为string类型,得到"false".因此,!(~+[])+{}的最终结果为"false[object Object]".
  • (!(~+[])+{})[--[~+""][+[]]*[~+[]]+ ~~!+[]]。基于上述分析,该表达式变成了"false[object Object]"[3],因此该表达式结果为's'.
        右半部分用同样的方法进行分析,最终得到的结果为'b'。因此,最终的结果为'sb'。

版权声明1:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/miffy2016/article/details/70158910
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2021-04-08 00:20
  • 阅读 ( 188 )

0 条评论

请先 登录 后评论

官方社群