JavaScript运算符规则

JavaScript运算符规则

从sb说起

console.log((!(~+[])+{})[--[~+""][+[]]*[~+[]]+~~!+[]]+({}+[])[[~!+[]]*~+[]])控制台输出此段字符,你会得到"sb"。
有没有那么点把丝头疼…让我们顶着头疼分析一下
运算符在这里(!(~+[])+{})[--[~+""][+[]]*[~+[]]+~~!+[]]+({}+[])[[~!+[]]*~+[]],从最开始出发,看能不能弄简单一丢丢
小括号里边的可以先算,没问题的吧?第一个小括号(!(~+[])+{}),先算里边的那个小括号,就是~+[]+[]默认把空数组转成数字,结果是数字0,~0结果是-1(~的运算规则)。
所以就是(!(-1)+{}),即(false+{}),加号两边没法加的时候会把两边都转换成字符串变成字符串的连接操作(自动数据类型转换),所以结果是("false[object Object]")。至此第一个小括号完成了。
中括号在js中要么是数组,比如[1,2,3]这一类,要么是用来取出对象的成员,比如obj["name"]这种。这里小括号和中括号之间没有任何运算符相连,我们可以知道后边肯定是取出对象的成员。把这个中括号单独拿出来是这一段[--[~+""][+[]]*[~+[]]+~~!+[]]
还是来慢慢分析。
[~+""],其中+""即把""转换成数字,也就是数字0(自动数据类型转换),~0的值为-1,所以是[-1]

[+[]]===[0]
[~+[]]===[~0]===[-1]

~~!+[]===~~!0===~~true===~(-2)===1,这一段比较关键的还是自动数据类型转换和~的运算规则
所以由上边的分析可以得到[--[~+""][+[]]*[~+[]]+~~!+[]] === --[-1][0]*[-1]+1,此时[-1]作为一个数组,[0]用来取出数组的第0个元素,所以是--(-1)*[-1]+1
--(-1)===-2,-2*[-1]会把后者转换成数字-1,所以结果是数字2,2+1结果是3。
第一阶段得到的结果是("false[object Object]")[3],取字符串的第四个字符,也就是s
继续算后面的({}+[])[[~!+[]]*~+[]]
({}+[])===("[object Object]0")
后边中括号里的先算前面的一半[~!+[]]===[~!0]===[~true]===[-2]
乘号后边的~+[]===~0===-1
所以是[-2]*(-1),即(-2)*(-1),结果是数字2。
所以("[object Object]0")[2],取字符串的第三个字符,也就是b
至此这个诡异的sb终于结束。
讲的不是太直观,可以配合下边拆分图食用。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hsbjgnRR-1578381325437)(https://i.loli.net/2019/10/15/VHFgZP5K1Ctrlpe.png)]

这里用到比较重要的是运算符导致的数据类型转换,~的运算规则,[]的使用,以及贯穿全局的运算符的优先级。
使用这个思路我们可以反推出其它的字符串,比如说Null。需要注意的是你所得到的操作数的数据类型。比如NaN的数据类型实际上是number,"NaN"才是string。
(+{}+{})[-[]] === (NaN+{})[-[]] === ("NaN[object Object]")[-[]] === ("NaN[object Object]")[0] === "N"
(!![]+[])[-(~[]+~[])] === (!false+0)[-(~[]+~[])] === ("true0")[-(~[]+~[])] === ("true0")[-( (-1) + (-1) )] === ("true0")[-(-2)] === ("true0")[2] === "u"
(![]+[])[-(~[]+~[])] === (false+0)[2] === ("false0")[2] === "l"
(![]+[])[-(~[]+~[])] === (false+0)[2] === ("false0")[2] === "l"
console.log((+{}+{})[-[]]+(!![]+[])[-(~[]+~[])]+(![]+[])[-(~[]+~[])]+(![]+[])[-(~[]+~[])]) //Null

标点符号导致的自动数据类型转换

加减乘除等基础运算中,除了加号,所有的基础运算符都会将运算符两边的运算子自动转换为Number类型。但是加号的话,只要两个运算子不都是Number类型,都会转成String类型。所以我们可以看到下面这奇怪的结果。

1+[1] === "11"   // string
1-[1] === 0      // number
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值