一行神奇的 javascript 代码
2017-04-13 16:02
134 查看
(!(~+[])+{})[--[~+""][+[]]*[~+[]] + ~~!+[]]+({}+[])[[~!+[]]*~+[]]
运行这段代码,结果有点意外。
其实这主要是运用到了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'。
相关文章推荐
- 一行神奇的javascript代码
- 一行神奇的javascript代码
- 一行神奇的javascript代码
- 一行神奇的javascript代码
- 一行神奇的javascript代码
- JavaScript talbe表中指定位置插入一行的实现代码 脚本之家修正版 转(http://www.jb51.net/article/18502.htm)
- 一行代码加速IE的javascript的方法
- JavaScript神奇的魔法代码
- JavaScript talbe表中指定位置插入一行的实现代码 脚本之家修正版
- 一行代码加速IE的javascript的方法
- 揭秘史上最昂贵的一行 JavaScript 代码
- [JavaScript]只需一行代码,轻松搞定快捷留言-V2升级版
- 一行代码加速IE的javascript的方法
- 这是有史以来最昂贵的一行 JavaScript 代码
- 研发周报:神奇!1KB JavaScript代码编写的3D蜜蜂
- 神奇的代码——JavaScript在浏览器中的妙用
- 【转】[JavaScript]只需一行代码,轻松搞定快捷留言功能 小助手功能
- 神奇的“魔法代码”-JavaScript
- 一行代码加速IE的JavaScript的方法!
- 揭秘史上最昂贵的一行Javascript代码