++[[]][+[]]+[+[]] = 10 这是为什么?(JS)

加号根据语境有三个用途:
1.取正
2.加法
3.连接字符串
当作为 “取正” 运算符时,会对非数字做一个隐式的数字转换。

转换规则如下:
true转换为1,false转换为0
null转换为0
undefined转换为NaN
空字符串转换为0
对象会调用valueOf()方法,如果该方法返回的是基本类型并且非数字,则按照上面的4种规则继续转换,如果返回的是对象类型,则会调用toString()方法,如果toString()方法返回的是基本类型并且非数字,则也按照上面的4种规则进行转换,如果toString()返回的也是一个对象,则转换失败,会引发错误。 

知道上面的转换规则后,我们再来分析这个表达式:
+[] 最终会转换为 0,为什么呢? 因为它的转换步骤是这样的,+[]中的加号此时是取正运算符,这意味着后面的运算数要被隐式的转换成一个数字,之前我们说过如果这个运算数是个对象的话,就会先调用它的valueOf()方法,我们发现对数组[]调用valueOf()方法,所返回的仍然是个对象,所以继续会调用[]的toString()方法,此时toString()方法返回一个空字符串,按照上面的转换规则,空字符串最终会被转换为0,所以+[]的最终运算结果是0

搞懂了+[]是如何运算的,相信下面的表达式就很容易理解了:
++[[]][+[]] 简化后变成 ++[[]][0] 
++[[]][0]     简化后变成 ++[]
最终复杂的 ++[[]][+[]] 变成了 ++[]
++[]会将数组转化为数字0,然后执行加1操作,所以运算结果是1.

在来看看我们那复杂的表达式简化成了这样:
1 +[+[]] = 10 ?
继续简化
1 +[0] = 10 ?
此时此刻已经很简单了吧? 呵呵,注意,这个时候的加号要变换角色了啊,因为这里是数字和对象相加,所以会先调用对象的valueOf()方法,我表达能力很差,所以就用伪代码了啊,请看: 
    var ret = 对象.valueOf();
    if( ret 是基本类型 ){
       if( ret 是字符串类型 ) {   
            执行字符串连接运算   
        }
        // true、false、NaN、undefined、number
       else{ 
            执行加法运算 
        }
   }
   //ret是个对象
   else{
        ret = 对象.toString();
        if( ret 是基本类型 ){
           if( ret 是字符串类型 ) {   
                    执行字符串连接运算   
            }
            // true、false、NaN、undefined、number
           else{ 
                执行加法运算 
            }
        }
        //ret是个对象
        else{
            报错;
        }
   }
所以最终的表达式,变成了 1+0(这个0是字符串) = 10
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值