(!(~+[])+{})[--[~+""][+[]]*[~+[]] + ~~!+[]]+({}+[])[[~!+[]]*~+[]]
运行这段代码,结果有点意外。

其实这主要是运用到了js的类型转换的基本原理。下面就揭秘“”sb“”是如何炼成的。
- 首先是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类型。
参数 | 结果 |
undefined | NaN |
null | +0 |
boolean | true转换为1,false转换为0 |
number | 无需转换 |
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
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。