您的位置:首页 > Web前端 > JavaScript

一行神奇的 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类型。

参数结果
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'。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: